anthropics / anthropics/claude-code
[BUG] Skill invocation loads the user-scoped skill even when a same-named project-scoped skill exists in cwd's repo
- Langage dominant
- Python
- Étoiles
- 145k
- Forks
- 23.1k
- Métriques de merge des PR
- Métriques de PR en attente
Description
[BUG] Skill invocation loads the user-scoped skill even when a same-named project-scoped skill exists in cwd's repo
**Claude Code version:** 2.1.232
**Summary**
When a user-scoped skill (`~/.claude/skills//SKILL.md`) and a project-scoped skill (`/.claude/skills//SKILL.md`) share the same name, invoking the skill from inside that project loads the **user-scoped** one — even though the working directory is inside the repo that has its own more-specific version.
This contradicts the documented resolution rule for the Skill tool, which states: *"Directory-scoped skills are listed with a path prefix... when both scoped and unscoped variants of a name exist, pick the one whose directory contains the files you're working on (most specific wins; unscoped otherwise)."* In this case the opposite happened: the unscoped (user-level) variant won even while actively working inside the directory that owns the scoped variant.
**Repro steps**
1. Create `/.claude/skills/eod-check/SKILL.md` inside a git repo, e.g. `~/projects/myrepo`.
2. Separately create `~/.claude/skills/eod-check/SKILL.md` (different content, e.g. with a distinguishing string in its body).
3. `cd ~/projects/myrepo`
4. Invoke the skill by name (`/eod-check`, or ask the assistant to use it).
5. Observe which file's content gets loaded — check the "Base directory for this skill:" line the harness prints when a skill launches.
**Expected**
Base directory reported as `/.claude/skills/eod-check` — the project-scoped, more specific version, per the documented resolution rule.
**Actual**
Base directory reported as `/Users//.claude/skills/eod-check` — the user-scoped (global) version, despite the session's cwd being inside `` and `/.claude/skills/eod-check/SKILL.md` existing and being non-empty at the time of invocation.
**Impact**
A project-scoped skill written specifically to override/specialize a same-named global one is silently never used from inside its own project — the opposite of the documented and presumably intended behavior. In our case the global skill's own body even says "prefer the project-scoped one if it exists," which the assistant had to notice and manually work around by re-reading the project file and re-running its instructions by hand, defeating the purpose of having two scoped variants at all.
**Workaround**
None automatic. The assistant can detect the mismatch (check `test -f /.claude/skills//SKILL.md` after the global one loads) and manually switch to following the project-scoped file's instructions instead, but this requires the global skill's author to have anticipated the collision and written explicit fallback-check instructions into the global skill's body — ordinary skills won't self-correct.
**Additional context**
Both files are named `eod-check` intentionally — the project one is a specialized, repo-specific version of the general-purpose global one, matching the pattern the tool description itself describes ("Directory-scoped skills are listed with a path prefix... most specific wins"). This is exactly the scenario that resolution rule exists for, and it did not apply.
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Piste de recherche
Start by locating the skill discovery and invocation entry point that chooses between ~/.claude/skills/ and /.claude/skills/. Reproduce the collision described in the issue, then add a regression test showing that the project-scoped skill is selected and its reported base directory is used.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- cli, tooling
- Type d'issue
- Bug
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 55/100