You added a custom skill under ~/.claude/skills/my-skill/ with a SKILL.md, restarted Claude Code, and typed /my-skill — but the CLI reports “skill not found.” Or worse: it does show up in /help, but never auto-triggers when you describe the matching task in natural language. Skills are loaded from a fixed set of directories at session start, validated against frontmatter rules, and surfaced to the model via a description block. If any link in that chain breaks — wrong path, missing name field, malformed YAML, or a vague description — the skill silently goes invisible. Once you know which step failed, the fix is a one-line edit.
Common causes
Ordered by hit rate, highest first.
1. Skill file is not at the expected path
Claude Code only scans a few directories: ~/.claude/skills/<skill-name>/SKILL.md, project-local .claude/skills/<skill-name>/SKILL.md, and plugin-provided skills. A skill placed at ~/.claude/skills/my-skill.md (flat file, no folder) or ~/.claude/skill/... (wrong dir name) will never be picked up.
How to judge: Run ls ~/.claude/skills/ and confirm each entry is a directory containing exactly SKILL.md.
2. Missing or malformed frontmatter
SKILL.md must start with YAML frontmatter containing at minimum a name and a description. A missing closing ---, smart quotes pasted from a doc, or tabs instead of spaces will make the parser skip the file.
How to judge: Open SKILL.md, confirm the first line is ---, the second is name: my-skill, and there is a closing --- before the body.
3. Skill name does not match the folder name
The name: field and the folder name must match exactly, including case and hyphens. If the folder is my-skill but the frontmatter says name: MySkill, the slash command will not resolve.
How to judge: Compare basename $(dirname SKILL.md) to the name: field character by character.
4. Description is too vague for auto-trigger
For auto-invocation (model decides to call the skill), Claude Code matches the user request against each skill’s description. A one-word description like “helper” or “stuff” gives the model nothing to match on, so it never fires unless you slash-invoke.
How to judge: Read your description aloud. If it does not mention concrete triggers (“when the user asks to deploy”, “for SQL migrations”), it is too vague.
5. Allowed-tools list excludes the tools the skill needs
If your frontmatter restricts allowed-tools: [Read] but the skill body invokes Edit or Bash, Claude Code may refuse to load it or silently drop the steps that need those tools.
How to judge: Cross-check the allowed-tools list against every tool name referenced in the skill body.
6. A stale or duplicate skill is shadowing yours
If both ~/.claude/skills/foo/ and a plugin ship a skill named foo, one wins and the other is hidden. Same with project-local vs user-global skills.
How to judge: Run claude --debug at startup and grep for “skill” — the loader logs which path won.
Before you start
- Confirm you are using the CLI Claude Code, not Claude.ai web (skills work differently).
- Have your skill folder path handy and ready to inspect.
- Make sure you have restarted Claude Code at least once since adding the skill (skills load at startup).
- Note whether you expect slash invocation, auto-trigger, or both.
Information to collect
- Claude Code version:
claude --version. - OS and shell:
uname -aplusecho $SHELL. - Output of
ls -la ~/.claude/skills/andls -la .claude/skills/from your project root. - The full contents of your
SKILL.md, especially the frontmatter block. - Startup debug log:
claude --debug 2>&1 | head -200. - Any error printed when you typed
/your-skill-name.
Step-by-step fix
Step 1: Verify the on-disk layout
ls -la ~/.claude/skills/
ls -la ~/.claude/skills/my-skill/
You should see a directory my-skill/ containing SKILL.md. If instead you see my-skill.md as a flat file, move it:
mkdir -p ~/.claude/skills/my-skill
mv ~/.claude/skills/my-skill.md ~/.claude/skills/my-skill/SKILL.md
Step 2: Validate the frontmatter
Open SKILL.md and check the top block:
---
name: my-skill
description: Use when the user asks to deploy the API service to staging.
---
The opening and closing --- are required. The name must match the folder. Avoid tabs and smart quotes.
Step 3: Run Claude Code in debug mode
claude --debug
Search the startup logs for lines mentioning skill, SKILL.md, or your skill name. You will see either “loaded skill my-skill” or an error like “failed to parse frontmatter.”
Step 4: Test slash invocation explicitly
In the session, type /my-skill and press Tab. If the skill exists, autocomplete shows it. If nothing appears, the loader rejected it — go back to Step 2.
Step 5: Improve the description for auto-trigger
Rewrite the description to include concrete trigger phrases:
description: |
Use when the user asks to deploy a service, run database
migrations, or invalidate the CDN cache. Examples:
"deploy api to staging", "run migration 0042".
Specific triggers dramatically increase auto-firing.
Step 6: Check allowed-tools coverage
If your skill body uses Bash, Read, Edit, and Write, the frontmatter should list each:
allowed-tools: [Bash, Read, Edit, Write]
Or omit allowed-tools entirely to inherit the session default.
Step 7: Resolve duplicate shadowing
If a plugin and your user-global skill share a name, rename one. The simplest fix is to prefix your skill folder, e.g. my-deploy instead of deploy.
Verify
/my-skillappears in tab-complete and prints the expected output.- A natural-language prompt matching the description triggers the skill within one or two turns.
claude --debugshows the skill in the loaded list with no warning.- The skill works in a fresh session, not just one that was open during the edit.
Long-term prevention
- Keep a
skills/README.mdin your dotfiles listing every skill and its trigger phrases, so you remember what is installed. - Use a linter or a simple script that walks
~/.claude/skills/and validates eachSKILL.mdfrontmatter. - Pin skill names with a personal prefix to avoid plugin collisions.
- When iterating on a description, test auto-trigger with two or three phrasings before considering it done.
- Version-control your
~/.claude/skills/directory.
Common pitfalls
- Editing
SKILL.mdand forgetting to restart Claude Code; skills load only at session start. - Copy-pasting frontmatter from a blog and importing smart quotes.
- Using uppercase or spaces in the folder name; stick to lowercase-hyphenated.
- Writing a 200-word description thinking more is better; the model truncates, keep it under 60 words but specific.
- Putting the skill in
~/.claude/skill/(singular) by typo.
FAQ
- Where does Claude Code look for skills?
~/.claude/skills/<name>/SKILL.mdfor user-global,.claude/skills/<name>/SKILL.mdfor project-local, plus any plugin-provided skills. - Do I need to restart after adding a skill? Yes. Skills are scanned at session start. Edits to an existing
SKILL.mdbody take effect on next session too. - Why does my skill show in
/helpbut never auto-fire? The description is too generic. Rewrite it with concrete trigger phrases and example user messages. - Can I list all loaded skills? Run
claude --debugand grep for “skill”; the loader prints each one it accepted. - Does the SKILL.md filename matter? Yes, it must be exactly
SKILL.md(uppercase).skill.mdorSkill.mdwill not be picked up on case-sensitive filesystems. - Can two skills share a name? No; one will shadow the other. Prefix your name to avoid conflicts with plugins.