·11 min read

Claude Skills Not Triggering? 7 Fixes That Work

Claude skills not triggering? Learn the 7 most common causes, from vague descriptions to silent YAML errors, and how to fix each one fast.

You wrote a skill, dropped it into .claude/skills/, and Claude acts like it doesn't exist. Claude skills not triggering is the most common problem developers hit after creating their first skill -- and it's frustrating precisely because nothing errors. The skill just sits there, silently ignored.

In almost every case, the cause is one of two things: the description in your SKILL.md frontmatter doesn't contain the words you actually type when prompting, or a formatting problem -- invalid YAML, wrong file location, a bad name -- prevents the skill from loading at all. Both failures are silent. This guide walks through the seven fixes that resolve nearly every report of Claude skills not working, in the order you should try them.

Why you see Claude skills not triggering

To debug activation, you need to know how it works. When a Claude Code session starts, it scans your skill directories, parses the YAML frontmatter of each SKILL.md, and injects only the name and description of each skill into context. The body of the skill is not loaded yet. Later, when you send a prompt, Claude compares your request against those descriptions and decides -- using plain language understanding, not regex or config -- whether a skill is relevant. Only then does it read the full skill body.

That two-stage design means there are two distinct failure modes, and they need different fixes:

SymptomFailure modeTry
Skill never appears when you ask "what skills do you have?"Not loading (parse or path problem)Fixes 2, 3, 4
Skill appears in the list but Claude never uses itNot activating (matching problem)Fixes 1, 5, 6, 7

Run that quick check first -- ask Claude to list its available skills -- and you'll immediately know which half of this guide applies. If you haven't built a skill yet and are just planning ahead, start with our step-by-step guide to creating a Claude skill and you'll avoid most of these problems from the start.

Fix 1: rewrite your skill activation description around trigger phrases

The skill activation description is the only signal Claude has when deciding whether to load your skill. Not the skill body, not the file name, not your intentions -- just that one frontmatter string. Most non-triggering skills have descriptions written like documentation summaries instead of matching rules.

Here's a description that will almost never trigger:

---
name: db-helper
description: Database utilities and helpers.
---

Nobody types "use database utilities" into a prompt. Compare:

---
name: postgres-migrations
description: Writes and reviews Postgres schema migrations with Drizzle ORM.
  Use when the user asks to add a column, create a table, write a migration,
  change the schema, or mentions drizzle-kit, ALTER TABLE, or migration files.
---

The second version works because it contains the literal phrases a developer actually types. Four rules for writing descriptions that trigger:

  1. Write in third person. The description is read by the model about the skill: "Writes and reviews...", not "I can help you with...".
  2. Lead with what the skill does, then add a "Use when the user..." clause listing concrete trigger phrases.
  3. Include the words your prompts contain. Tool names, library names, file names, error messages. If you'd type "drizzle-kit", the description should say "drizzle-kit".
  4. Cover synonyms. "Add a column", "change the schema", and "write a migration" are three phrasings of the same intent -- list all three.

A good stress test: write down the last five prompts where you wished the skill had fired, and check whether the description shares meaningful words with each one. If not, add them.

Fix 2: validate frontmatter -- SKILL.md YAML errors fail silently

This is the sneakiest failure. If the YAML between the --- markers doesn't parse, the skill is skipped entirely -- no warning, no error message, nothing. SKILL.md YAML errors are behind a huge share of "my skill vanished" reports.

The classic culprit is an unquoted colon inside the description:

---
name: api-review
description: Reviews REST endpoints: auth, validation, and error handling.
---

That second colon makes the parser see a nested mapping where a string should be, and the whole document fails. Quote the value and it loads:

---
name: api-review
description: "Reviews REST endpoints: auth, validation, and error handling."
---

Other frequent offenders:

  • Smart quotes (" ") pasted from a doc or chat window instead of straight quotes
  • Tabs for indentation -- YAML requires spaces
  • A missing closing ---, so the entire file is treated as frontmatter
  • Multi-line descriptions without proper indentation on the continuation lines

You can validate in one command before blaming anything else:

python3 -c "
import yaml, pathlib
raw = pathlib.Path('.claude/skills/api-review/SKILL.md').read_text()
print(yaml.safe_load(raw.split('---')[1]))
"

If that prints a dict, your YAML is fine. If it throws, you've found the bug. For the full list of supported frontmatter fields and their constraints, see our SKILL.md format reference.

Fixes 3-5: location, naming, and scope problems

If your Claude Code skills are not loading at all -- they never show up when you ask for the skill list, and the YAML parses cleanly -- the problem is almost always where the file lives or what it's called.

Fix 3: put SKILL.md exactly where Claude looks

Claude Code discovers skills in two places:

your-project/
  .claude/
    skills/
      postgres-migrations/
        SKILL.md          # project skill: loads in this project
~/.claude/
  skills/
    git-hygiene/
      SKILL.md            # personal skill: loads in every project

Three gotchas account for most misses:

  1. The file must be named SKILL.md exactly -- uppercase, with the .md extension. skill.md, Skill.md, and SKILLS.md are all invisible.
  2. Each skill needs its own folder. A SKILL.md dropped directly into .claude/skills/ won't load; it has to be .claude/skills/<skill-name>/SKILL.md.
  3. Project skills are relative to where you launched Claude Code. If you start a session from a sibling directory or a subfolder outside the project root, the project's .claude/skills/ may never be scanned. Launch from the directory that contains .claude/.

Fix 4: fix the skill name

Skill names should be lowercase letters, numbers, and hyphens -- no spaces, no underscores, no capitals -- and kept under 64 characters. Two more rules that trip people up:

  • The name in frontmatter should match the folder name. A folder called API_Review holding a skill named api-review is asking for trouble.
  • Make the name descriptive enough to reinforce the description. postgres-migrations gives the model one more matching signal; helper2 gives it nothing.

Fix 5: right-size the scope

Scope problems break activation in both directions:

  • Too broad: a skill described as "Helps with frontend development" competes with everything Claude already knows. There's no clear moment when it obviously applies, so it rarely gets picked.
  • Too narrow: a skill that only mentions "Use when converting XLSX exports from the billing dashboard" won't fire when you say "parse this spreadsheet."

The fix is one job per skill, described at the level your prompts operate at. If you've built a mega-skill covering testing, linting, and deployment, split it into three -- each with its own tight trigger phrases. Smaller skills trigger more reliably and cost less context when they do.

Fixes 6-7: conflicting skills and context-window pressure

If a skill loads fine and has a solid description but still fires inconsistently, look at the rest of your skill library.

Fix 6: resolve overlapping skills

When two skills both plausibly match a prompt, Claude has to choose -- and it may pick the wrong one, or neither. This shows up constantly with skills like testing-conventions and jest-unit-tests living side by side, both claiming anything test-shaped.

Fix it by drawing explicit boundaries inside the descriptions themselves:

description: Writes unit tests with Jest and React Testing Library.
  Use for component and function-level tests. For browser end-to-end
  tests, use the playwright-e2e skill instead.

Cross-referencing skills in each other's descriptions turns an ambiguous choice into an explicit routing rule. If you inherited a pile of overlapping skills from different teammates, consolidating them into one shared, versioned library -- see how teams share Claude skills -- fixes the conflict at the source.

Fix 7: relieve context-window pressure

Every loaded skill's name and description sits in Claude's context for the entire session. A handful of skills is negligible. Fifty skills with 500-character descriptions is a wall of competing instructions, and reliability drops -- especially deep into a long conversation, when your original request is thousands of tokens behind the current exchange.

Three mitigations:

  1. Prune. Remove or relocate skills you haven't used in weeks. Personal skills you only need in one repo should be project skills, not global ones.
  2. Consolidate overlap (see Fix 6) so fewer descriptions compete per intent.
  3. Start fresh sessions per task type. A new session reloads skills into the front of context, where matching is at its sharpest.

How to verify a skill loaded and test activation

Work through this sequence and you'll pinpoint any activation failure in about two minutes:

  1. Start a fresh session. Skills are scanned at session start, so a skill created mid-session doesn't exist yet as far as Claude is concerned. This alone resolves a surprising number of "broken" skills.
  2. Ask for the inventory: "What skills do you currently have available?" Claude answers from the metadata in its context. If your skill is missing, it never loaded -- go to Fixes 2-4.
  3. Invoke it explicitly: "Use the postgres-migrations skill to add a created_at column to users." If explicit invocation works but automatic activation doesn't, loading is fine and your description is the problem -- go to Fix 1. If Claude says it doesn't have that skill, it's a loading problem.
  4. Test implicit activation with a realistic prompt containing one of your trigger phrases, phrased the way you'd naturally type it. This is the test that actually matters day to day.
  5. Run claude --debug if you're still stuck. Debug output at startup surfaces parsing and loading details that normal sessions swallow.

One more failure mode worth naming: the skill triggers on your machine but not your teammate's. That's almost never an activation bug -- it's diverged copies. One of you edited the description locally and the other has last month's version. The durable fix is publishing the skill once to a registry and installing it everywhere: localskills.sh versions every skill (with rollback), and one localskills install writes the tool-native format for each target -- .claude/skills/ for Claude Code, .cursor/rules for Cursor, .windsurf/rules/ for Windsurf -- so everyone triggers the same description. For a broader tour of how skills fit into Claude Code, see the complete Claude Code skills guide.

FAQ: Claude skills not triggering

Why doesn't my skill show up at all in Claude Code?

If a skill never appears when you ask Claude to list its skills, it failed to load: the YAML frontmatter doesn't parse (Fix 2), the file isn't at .claude/skills/<name>/SKILL.md or ~/.claude/skills/<name>/SKILL.md (Fix 3), or the name breaks the lowercase-and-hyphens convention (Fix 4). Loading failures are silent, so validate the YAML first -- it's the most common cause.

Do I need to restart Claude Code after adding a skill?

Yes. Skill discovery happens at session start, so a skill added mid-session won't be picked up until you start a new session. If you just created or renamed a skill and it seems dead, restart before debugging anything else.

How do I force Claude to use a specific skill?

Name it in your prompt: "Use the api-review skill to check this endpoint." Explicit invocation bypasses description matching entirely, which also makes it a great diagnostic -- if the skill works when named but not otherwise, your description needs better trigger phrases, not your skill body.

How long should a SKILL.md description be?

Long enough to include your trigger phrases, short enough to stay under the roughly 1,024-character limit. In practice, one sentence saying what the skill does plus a "Use when the user..." clause with 5-10 concrete phrases lands around 200-400 characters, which is the sweet spot: specific enough to match, small enough not to bloat context.

Why does my skill trigger in one project but not another?

Usually it's a project skill (.claude/skills/ inside one repo) rather than a personal skill (~/.claude/skills/), so it only exists in that project. If it should follow you everywhere, move it to your personal directory -- or publish it to a shared registry and install it per project so every copy stays current.


Tired of debugging seven slightly different copies of the same skill? Sign up for localskills.sh and publish it once -- versioned, shareable, and installable into every tool your team uses.

npm install -g @localskills/cli
localskills login
localskills publish