Skip to content

fix(skill_manage): _find_skill follows symlinked skill directories - #56420

Closed
val-spc wants to merge 4 commits into
NousResearch:mainfrom
val-spc:fix-skill-find-symlinks
Closed

fix(skill_manage): _find_skill follows symlinked skill directories#56420
val-spc wants to merge 4 commits into
NousResearch:mainfrom
val-spc:fix-skill-find-symlinks

Conversation

@val-spc

@val-spc val-spc commented Jul 1, 2026

Copy link
Copy Markdown

Problem

Path.rglob does NOT descend into symlinked directories. Skills installed as directory symlinks (common in multi-profile setups and managed deployments where ~/.hermes/skills/<namespace>/<slug> symlinks into a git checkout) are invisible to rglob — but the skill loader (iter_skill_index_files in agent/skill_utils.py) uses os.walk(followlinks=True) and finds them fine.

This discrepancy meant skill_view could load a skill but skill_manage could not find it for editing — returning "Skill '<name>' not found in active profile 'default'" on every call. In our SPC deployment this caused 575+ errors in 2 weeks across all 47 symlinked skills.

Fix

Replace both rglob("SKILL.md") call sites in skill_manager_tool.py:

  1. _find_skill (line ~581)
  2. _find_skill_in_other_profiles (line ~644)

with iter_skill_index_files(skills_dir, "SKILL.md"), which is the same function the skill loader uses. The import already exists in agent.skill_utils.

Tests

Two new tests in TestFindSkillSymlinks:

  • test_find_skill_follows_symlinked_dir — verifies _find_skill can resolve a skill whose directory is a symlink
  • test_find_skill_in_other_profiles_follows_symlinks — verifies the cross-profile search also follows symlinks

All 109 existing skill_manager_tool tests pass.

Impact

This bug affects any deployment where skills are installed as directory symlinks — which is the default behavior when using multiple profiles or managed dotfiles checkouts. The skill_resolver plugin hook (if present) self-heals skill_view failures but does NOT intercept skill_manage, which goes through a separate _find_skill() code path.

Co-authored-by: Sahil Shubham sahil@southparkcommons.com

val-spc and others added 4 commits July 1, 2026 19:00
Path.rglob does NOT descend into symlinked directories. Skills installed
as directory symlinks (common in multi-profile setups and managed
deployments where ~/.hermes/skills/<namespace>/<slug> symlinks into a
git checkout) are invisible to rglob — but the skill *loader*
(iter_skill_index_files in agent/skill_utils.py) uses
os.walk(followlinks=True) and finds them fine.

This discrepancy meant skill_view could load a skill but skill_manage
could not find it for editing — returning "Skill '<name>' not found in
active profile 'default'" on every call. In our SPC deployment this
caused 575+ errors in 2 weeks across all 47 symlinked skills.

Fix: replace both rglob("SKILL.md") call sites in skill_manager_tool.py
(_find_skill and _find_skill_in_other_profiles) with
iter_skill_index_files(skills_dir, "SKILL.md"), which is the same
function the loader uses. The import already exists in agent.skill_utils.

Tests: two new tests in TestFindSkillSymlinks verify _find_skill and
_find_skill_in_other_profiles can resolve a skill whose directory is a
symlink. All 109 existing skill_manager_tool tests pass.

Co-authored-by: Sahil Shubham <sahil@southparkcommons.com>
Path.rglob does NOT descend into symlinked directories. Skills installed
as directory symlinks (common in multi-profile setups and managed
deployments where ~/.hermes/skills/<namespace>/<slug> symlinks into a
git checkout) are invisible to rglob — but the skill *loader*
(iter_skill_index_files in agent/skill_utils.py) uses
os.walk(followlinks=True) and finds them fine.

This discrepancy meant skill_view could load a skill but skill_manage
could not find it for editing — returning "Skill '<name>' not found in
active profile 'default'" on every call. In our SPC deployment this
caused 575+ errors in 2 weeks across all 47 symlinked skills.

Fix: replace both rglob("SKILL.md") call sites in skill_manager_tool.py
(_find_skill and _find_skill_in_other_profiles) with
iter_skill_index_files(skills_dir, "SKILL.md"), which is the same
function the loader uses. The import already exists in agent.skill_utils.

Tests: two new tests in TestFindSkillSymlinks verify _find_skill and
_find_skill_in_other_profiles can resolve a skill whose directory is a
symlink. All 109 existing skill_manager_tool tests pass.

Co-authored-by: Sahil Shubham <sahil@southparkcommons.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have tool/skills Skills system (list, view, manage) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants