Skip to content

fix: make global skill install idempotent for already-installed skills#2110

Merged
jolestar merged 1 commit into
mainfrom
fix/global-skill-install-idempotent
Jul 4, 2026
Merged

fix: make global skill install idempotent for already-installed skills#2110
jolestar merged 1 commit into
mainfrom
fix/global-skill-install-idempotent

Conversation

@jolestar

@jolestar jolestar commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Creating an agent with a template that declares skills already present in the global skills directory (~/.agents/skills/) failed with Failed to create agent (HTTP 500).

Root cause

install_github_remote_skill treats an existing target directory as SkillInstallConflict and errors out. When the same skill (e.g. ghx, github-issue-solve) is shared by multiple templates and is already installed globally, subsequent agent creation attempts trigger the conflict and abort template initialization.

Fix

Make global skill install idempotent: if the skill already exists in the global directory, skip download and return success directly. The downstream resolve + link-to-agent logic is unaffected.

Verification

  • cargo build passes
  • cargo test passes

Template initialization failed with SkillInstallConflict when creating an
agent from a template whose skills (e.g. ghx) were already installed at the
user-global level. install_github_remote_skill now treats an existing
destination as idempotent (skip download) instead of erroring, since the
caller still resolves and links the skill to the agent afterwards.
@vercel

vercel Bot commented Jul 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
holon Ready Ready Preview, Comment Jul 4, 2026 4:52pm

@jolestar jolestar left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Clean idempotency fix.

  • Correctness: Catching SkillInstallConflict specifically and returning Ok(()) is the right approach — the skill files are already present from a previous install, so skipping the download is correct.
  • Callers safe: Both call sites (single install at L549 and batch install at L917) only need Ok(()) to proceed; they derive the skill name from the source, not the destination, so subsequent linking/resolution is unaffected.
  • Error scoping: Non-conflict errors (e.g. validate_skill_name failures) still propagate correctly.
  • Observability: Good tracing::info! log for the skip path.

No blocking issues. Will merge once CI passes.

@holonbot holonbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Holon Review — PR #2110

Verdict: Clean, minimal, and correct fix. No blocking issues.

What this does

Fixes a crash (SkillInstallConflict → HTTP 500) when creating an agent from a template whose skills are already installed globally. The fix catches SkillInstallConflict via downcast_ref and returns Ok(()) to skip re-download.

Correctness ✓

  • downcast_ref::<SkillInstallConflict>() correctly discriminates conflict errors from validate_skill_name errors (which still propagate via the catch-all arm).
  • Both call sites (add_global at L549, batch install at L928) only need Ok(()) to proceed — they derive skill names from the source, not the destination, so downstream linking is unaffected.
  • SkillInstallConflict implements std::error::Error + .into(), compatible with anyhow::Error::downcast_ref.

Safety ✓

  • No trust-boundary concerns — local filesystem check only.
  • Concurrent installs both safely return Ok(()).

Observability ✓

  • tracing::info! log for the skip path includes skill_name and destination.

Minor observation (non-blocking)

When a global skill exists from a different version/ref, the old version is preserved without a staleness check. This is the correct minimal fix for the described bug; a future enhancement could compare installed metadata against the requested version.

@holonbot

holonbot Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Holon Run Report

@jolestar
jolestar merged commit 63678a1 into main Jul 4, 2026
5 checks passed
@jolestar
jolestar deleted the fix/global-skill-install-idempotent branch July 4, 2026 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant