Claude Code Skill Not Triggering? Work Through These 8 Causes
A skill that never fires almost always has one of eight problems, and the first six are configuration you can check in about two minutes: the wrong directory, the wrong filename, broken frontmatter, a description the agent cannot match, invocation that is disabled by design, or a session that predates the install. The last two take longer to spot: skill overload and per-agent differences.
The frustrating part is the silence. A misplaced or malformed skill produces no error message anywhere; the agent simply behaves as if it does not exist. To make each failure concrete, we built a demo project with one working skill and three broken ones, and every file listing below comes from that real reproduction.

The checklist
How a skill gets triggered in the first place
When a session starts, the agent scans its skill directories and collects one thing from each skill: the description field in the SKILL.md frontmatter. The instruction bodies stay on disk. When you send a request, the agent compares it against those descriptions, and only a skill whose description matches gets its full instructions loaded.
That design explains every failure mode on this page. Files outside the scanned directories never enter the candidate list. Broken frontmatter means no description to collect. A vague description matches nothing. And since collection happens at session start, a mid-session install stays invisible until you restart. Each check below targets one link in that chain.
1. Wrong directory or nesting
Claude Code looks for project skills at .claude/skills/<skill-name>/SKILL.md and personal skills at ~/.claude/skills/<skill-name>/SKILL.md. The file must sit exactly one folder deep. Here is the skills tree of our demo project, which contains one working skill and three broken ones:
$ find .claude/skills -type f | sort
.claude/skills/Deploy-Helper/skill.md
.claude/skills/changelog/changelog/SKILL.md
.claude/skills/lint-fixer/SKILL.md
.claude/skills/pdf-tools/SKILL.md The changelog skill is the directory failure: unzipping or cloning into an existing folder produced changelog/changelog/SKILL.md, two levels deep, so the scanner never finds it. Move the inner folder up one level. The same class of failure covers skills dropped directly into .claude/skills/SKILL.md with no skill folder at all, and skills placed in a directory the agent does not scan.
2. Filename case
The filename is SKILL.md, uppercase SKILL, lowercase md. In the listing above, Deploy-Helper ships a lowercase skill.md, and that single detail takes it out of the scan with no warning. This one bites macOS users hardest: the default filesystem is case-insensitive, so the file opens fine in your editor and every local test you run by hand, and then a case-sensitive lookup ignores it.
Deploy-Helper also demonstrates the naming rules: skill names must be lowercase with hyphens, so the capital letters in its name and folder are a second, independent reason it stays dead even after the file is renamed.
3. Broken frontmatter
The frontmatter needs a name and a description, fenced by --- on both sides, with the folder name matching the name field. Our lint-fixer repro breaks the least visible of those rules:
$ cat .claude/skills/lint-fixer/SKILL.md
---
name: lint-fixer
description: Fixes lint errors
allowed-tools: Read, EditThere is no closing fence, so the YAML never terminates and the whole file parses as garbage. The fix takes one line, which is what makes this class of failure so annoying to find by eye. Other frontmatter breakers from real reports: multi-line descriptions that break YAML parsing (keep it one quoted line), XML tags inside the description, and a folder renamed without updating the name field. When in doubt, run the file through any YAML linter before blaming anything else.
4. A description with nothing to match
This is the big one once the files are valid: the skill loads, shows up in listings, and still never fires. The description is the only signal the agent has at selection time, so a description like Deployment helper (our Deploy-Helper repro again) gives it almost nothing to match against a request like ship this to staging.
Compare the description that our one working skill ships:
description: Extract text and tables from PDF files. Use when
the user asks to read, parse, or convert a PDF.It names the capability and then lists the request shapes it should answer. Write descriptions the way users phrase problems, put the trigger phrasing early, and keep the whole thing concise since long descriptions can get truncated in the collected list. One more gotcha from real reports: two installed skills with near-identical descriptions compete, and the agent picks one of them, which reads as the other skill randomly failing.
5. Invocation is disabled on purpose
Some skills are built to never trigger automatically. A frontmatter flag of disable-model-invocation: true tells the agent to load the skill only when you invoke it by name. Skill authors use it for workflows that take over the whole session, where an accidental trigger would be a bad surprise. Matt Pocock's writing skills, covered in our writing and documentation guide, all ship with the flag set for exactly that reason.
So before debugging a popular skill that will not auto-fire, open its SKILL.md and check for the flag. If it is there, nothing is broken. Call the skill by name and it runs.
6. Stale session
Descriptions are collected at session start, so a skill installed mid-conversation does not exist as far as the running session is concerned. The fix is to start a new session, and for cached skill dialogs a full restart of the app or CLI. Trivial, and still worth listing first when you debug, because every minute spent checking frontmatter on a skill the session has never seen is wasted.
7. Too many skills
Skill descriptions share the context budget with everything else in a session, and there is a point where the agent stops loading all of them. GitHub issue reports describe installs of 137 skills where only 116 load, with the rest silently absent: no error, no warning, just skills missing from the working set. If a skill that worked last week stopped after you installed a big collection, this is the first suspect.
The fix is unglamorous: uninstall what you do not use, and shorten verbose descriptions, since total description volume is what fills the budget. Collections that install a dozen skills at once are the usual way installs quietly cross the line.
8. Different agents, different rules
The same SKILL.md behaves differently across surfaces, and files that work in one place can be invisible in another. Three differences cause most of the confusion. Claude Code auto-scans its skill directories, while the desktop app has been reported to need skills registered through its settings before files copied into place show up. Plugin-delivered skills have open issues where the Skill tool announces the launch but the instruction body never gets injected; reading the skill's SKILL.md into the conversation manually is the working workaround. And other agents scan their own paths, so a skill installed for one agent is simply not installed for its neighbor.
The practical rule: verify per agent instead of assuming. A skill is not installed in the abstract, it is installed for a specific agent on a specific machine.
Or let LazySkills run this checklist for you
Diagnosing this by hand means checking paths, filenames, frontmatter, and per-agent visibility one at a time. LazySkills is a terminal UI that does the sweep in one screen: it scans every skill directory on your machine, shows which agents can see each skill, and flags broken configurations like the four reproductions on this page.
curl -fsSL https://lazyskills.sh/install | shFrequently asked questions
Do I need to restart Claude Code after adding a skill?
Yes. Skill descriptions are collected when a session starts, so a skill added mid-session is invisible until you open a new one. This is the single most common reason a freshly installed skill seems broken. Restart before debugging anything else.
The skill shows in /skills but never fires. Why?
Listed means loaded, and firing is a separate step. The agent picks skills by matching your request against each description, so a vague description like helps with code gives it nothing to match. Rewrite the description to lead with trigger phrasing, naming the requests it should respond to. Also check the frontmatter for disable-model-invocation: true, which makes a skill name-invoked on purpose.
Can I force a skill to run?
Yes, and it doubles as a diagnostic. Invoke the skill by name, or write a prompt that mentions it explicitly, like use the pdf-tools skill for this. If explicit invocation works but natural phrasing never does, the files are fine and the description is the problem.
How many skills is too many?
Every description you install occupies context in every session, and GitHub issue reports describe installs in the 130-plus range where some skills silently stop loading. Symptoms are eerie: a skill that worked yesterday is absent today with no error anywhere. Prune what you do not use and keep descriptions short, since total description volume is what costs you.
What is the difference between a skill and a slash command?
A slash command is an explicit call: you type the name, it runs. A skill is model-invoked: the agent reads your request, matches it against installed skill descriptions, and loads the one that fits. Skills with disable-model-invocation: true sit in between, packaged like skills but fired like commands. If you always want manual control, that flag gives it to you.
Do these fixes apply to Codex, Cursor, and other agents?
The file format is portable and the failure modes travel with it: wrong directory, filename case, broken frontmatter, and weak descriptions break skills everywhere. What changes per agent is the search path and how invocation is exposed. Installing through npx skills add or the LazySkills TUI places files in the right location for each agent, which removes the directory class of failures entirely.