OpenSpec Spec Generator field notes
Claude Code skills ยท field notes

Claude Code skills: why yours never fires, and what actually fixes it

The short answer: if your skill installed and nothing happens, the problem is almost never the installation. It is the description field in SKILL.md. The model decides whether to load a skill by reading that one line, and a line that names a capability instead of naming a situation gets ignored. One rewrite of that line took an invocation rate from about 5 percent to about 80 percent, on the same skill, with the same task.

The second most common cause is not an error at all. You edit SKILL.md while a session is open, and the running process keeps using the version it read at startup. About eight times out of ten the edit does nothing. There is a reload command and it reports success, but it does not rescan the directories. You have to start a new process.

On Windows there is one more that everyone hits once: a skill that ships a .ps1 file dies with check-rules.ps1 cannot be loaded because running scripts is disabled on this system. That is the machine execution policy, and it is one command to fix.

Everything below is the detail, with the text each failure actually prints.

Seven ways a Claude Code skill fails, with the text it prints

Ordered by how often they come up. Every string is reproduced as it appeared.

Failure 1

It installs and is never invoked

Environment: Claude Code v2.1.x, Windows 10 and 11, skill under C:\Users\<user>\.claude\skills\

There is no error. The model answers normally and never mentions the skill. The usual description looks like a label for a tool, something like API interface design audit tool. A label does not tell the model when to reach for it, so it never does.

The version that worked names the situation and then the literal words a person would type:

# before, a label that names the tool
description: API interface design audit tool

# after, the situation plus the literal words a user would type
description: API design review. Use when the user says review the API, check the interface design, or audit endpoints.

Measured on the same task, the same skill, with nothing else changed: about 5 percent before, about 80 percent after. A three way test of the same idea put a bare capability line at about 5 percent, a line with the situation at about 40 percent, and a line with the situation plus the literal trigger phrases at about 85 percent.

Two things are happening in that line. The first half says when. The second half says what the user will actually type, including the casual and the half English versions people really use, because that is what arrives in the request.

Failure 2

A script bundled with the skill refuses to run

check-rules.ps1 cannot be loaded because running scripts is disabled on this system.

Environment: Windows 10 and 11, PowerShell, skill calling a .ps1 from its own folder

This is the machine execution policy, not the skill. Fix it once per machine:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Then close the shell and open a new one. The old one keeps the old policy.

Failure 3

The model id is rejected on every call

deepseek-v4-pro is not a model this version of claude code recognizes

"deepseek-v4-pro" is not a model this version of claude code recognizes

Environment: Node.js 18+, installed with npm install -g @anthropic-ai/claude-code, model set through CLAUDE_CODE_MODEL or the ANTHROPIC_MODEL entry in the env block of ~/.claude/settings.json

Three different spellings of the same variable exist across the user level file, the project level file and the shell, and the project level one wins. So people fix the user level file, see no change, and conclude the skill is broken. Check both files and keep the model id in exactly one place.

On Windows, before debugging anything else, run chcp 65001. Without it the console mangles non ASCII output and every error you read is half garbage.

Failure 4

529, 401 and 429, which are three different problems

Environment: Claude Code pointed at a third party endpoint

A 529 is upstream capacity. It is not a local fault and retrying is the whole fix:

for i in 1 2 3; do claude -p "..." && break; sleep 15; done

A 401 or 429 usually means the key is sitting in the wrong place. Written into a project file, it travels with the repository, gets shared, and starts hitting per project limits. Put it in the user level settings file and keep it out of anything that gets committed.

Failure 5

You edit SKILL.md and nothing changes

Environment: any long running session

About eight times out of ten, an edit made while the session is open is invisible to that session. The reload command answers politely and still misses it:

Reloaded skills: 72 skills available (no changes)

The workaround is not a setting. Start a new process. A fresh process lists the new skill immediately, including one written to disk after the session began:

claude -p '/skill-doctor'

If you are iterating on a description, that means one process per attempt. It is slow and it is the only thing that is reliable.

Failure 6

The wrong skill loads

Environment: two or more skills whose descriptions overlap

When two descriptions share trigger words, one of them loads and it looks arbitrary which one. This is not a bug you can report, it is two descriptions that both match. Give each one an exclusive keyword so a given request can only match one of them.

There are also two frontmatter switches that make a skill look like it never ran. disable-model-invocation: true does what it says, and it has to be false for the model to be able to reach the skill on its own. A skill declared with context: fork does its work away from the conversation you are watching, which reads exactly like nothing happened. Leaving context unset was the fix that held.

Failure 7

The skill runs and the output is wrong or goes missing

Environment: skills that execute their own scripts

Four errors account for most of it, and each has a check you can run before you test the skill at all:

ErrorWhat it means hereThe check to run first
ModuleNotFoundErrorThe dependency is not in the interpreter the skill actually usespython -m py_compile scripts/process.py
FileNotFoundErrorA relative path resolved against the wrong working directoryResolve every path from the skill root
PermissionErrorThe bundled shell script is not executablebash -n scripts/run.sh then set the bit
SyntaxErrorBroken YAML header or broken scriptConfirm --- on both ends and one space after every colon

Output going to an unexpected place is the same class of problem. Pick one directory for every artefact a skill produces and write there, always. Skills that scatter files across the working directory look like they produced nothing.

Whether a skill fires at all depends on what you asked

This is the part that makes skills feel random until someone tells you. The loader is more likely to reach for a skill when the request looks like a procedure, and it tends to answer directly when the request looks like a single step.

The requestShapeWhat tends to happen
Read this PDFSingle step, one artefactUsually answered directly, no skill loaded
Extract the tables from this PDF and batch convert them to ExcelMulti step, several artefactsA matching skill is loaded almost every time
Analyse this fileVague, no deliverable namedDirect answer, and often not the one you wanted
Analyse this sales CSV, compute the monthly trend, produce a standardised table and state the conclusionNamed input, named steps, named outputSkill loaded, output matches what you asked for

So the test instruction matters as much as the description. If you are checking whether a skill triggers, do not test it with a two word prompt. Test it with the sentence a real user would say, with the input, the steps and the deliverable all named in it.

The other half is a cap that is easy to miss. description and when_to_use are concatenated, and the combined text is truncated at 1536 characters in the skill listing. This one is in the official documentation, but it is buried in the field reference and almost nobody reads it before writing their first skill. Everything you wrote past that point is read by nobody. Put the trigger words in the first hundred characters, not the second thousand.

A setup you can finish, in this order

Twelve steps, in order. Each one assumes the previous one is done.

  1. Confirm the runtime before you install anything. node --version, and you want 18 or newer. Most of the strange failures below turn out to be an older Node.
  2. Install the CLI and read the version back. npm install -g @anthropic-ai/claude-code then claude --version. Write the version down. You will need it later, because several behaviours below changed between builds.
  3. Get the bare tool working first. One prompt, one answer, nothing installed. If this does not work, no skill will, and every skill symptom you see from here on is really this.
  4. Put the credentials at user level only. In ~/.claude/settings.json, in the env block. Project level settings override user level, so a key in a project file wins, gets shared, and produces 401 and 429 for reasons that have nothing to do with your skill.
  5. On Windows, do two things now. chcp 65001 for the console, and Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser for any skill that ships a .ps1. Restart the shell after the second one.
  6. Install two or three skills, not a bundle. The temptation is to install a collection of twenty. Do not. Every installed skill directory has a cost that is charged whether or not the skill is used, and a bundle also gives you overlapping trigger words on day one.
  7. Get the file name and the directory name exactly right. The file is SKILL.md, in capitals. The directory has no spaces and no non ASCII characters. A lowercase skill.md is silently not a skill, and the loader does not tell you.
  8. Write the description as situation plus trigger words plus boundary. Name when it applies, quote the phrases users actually type, and add one exclusive word so a neighbouring skill cannot also match. Keep it inside the first 1536 characters of the combined field, and well inside that if you can.
  9. Keep the body short and put the hard rules where they cannot be skipped. Under 500 lines, and under ten numbered steps. Anything longer and the model starts choosing which instructions to follow. The constraints you cannot afford to have skipped go in a section named Important constraints, near the top.
  10. Never write an absolute path into the body. Use a project relative convention instead. A hardcoded C:\... works on exactly one machine and fails silently on every other one.
  11. Add one line that proves the body was read. Put this at the top of the body: when you run this skill, first print that you have read this skill. Debugging a skill that might not be loading is guesswork without it.
  12. Test in a new process, every single time. Edit, exit, start a new process, send the full realistic instruction, look for the confirmation line. /reload-skills reporting no changes is not evidence that your edit landed.

If a step fails with a 529, wrap the call in the retry loop from Failure 4 and run the step again before you change any configuration.

The failure matrix, as a file you can keep

Every failure on this page, with the exact text, the environment it appeared in, the cause and the fix, in one CSV. It is a real file on this site, not something generated in your browser. Download it, or fetch it with curl:

https://openspec-mvp.pages.dev/claude-code-skills-failure-matrix.csv
curl -O https://openspec-mvp.pages.dev/claude-code-skills-failure-matrix.csv

19 rows, UTF-8 with a BOM so it opens correctly in Excel. Columns: Symptom, Exact text you see, Environment where it was seen, Root cause, Fix that worked, First reported.

The numbers, by date and by who reported them

None of these are benchmarks. They are what one person or one vendor measured on their own setup, and they are dated so you can judge how far your setup has drifted since. Where the number came from the vendor that sells the scanner, it says so.

DateWho reported itWhat the number wasWho measured it
2026-02-05 A security vendor's published audit of a public skill registry 3,984 skills scanned. 13.4% (534) carried at least one critical finding. 36.82% (1,467) carried at least one security flaw. 76 were confirmed malicious by human review. 8 of those were still publicly installable on the day the report went out. The vendor, on its own scan. Vendor reported.
2026-01 The same vendor, describing a three week campaign in late January 12 compromised publisher accounts, 341 to 1,184+ malicious skills published, 9,000+ installs observed The vendor. Vendor reported, and the count was still moving when it was written.
2026-09-18 One user filing a bug against the CLI, still open Idle CPU in the terminal went from 1.0% with no skills to 4.9% with 40 user skills, on Claude Code 2.1.276, Windows 11 Pro build 10.0.26200, Ryzen 9 3950X. Roughly 45 syscalls per second and roughly 0.07 to 0.1% of one core per skill directory. The person who filed it, on their own machine. Self reported.
2026-09-13 One user filing a bug, still open The reload command answered Reloaded skills: 72 skills available (no changes) for a skill added to disk mid session, on desktop 2.1.266 and CLI 2.1.263. A fresh process saw the same skill. The person who filed it. Self reported.
2026-03-27
(closed 2026-04-26)
One user filing a bug, now closed 43 skills injected silently into the session, about 3,950 tokens, roughly 6,000 tokens per session in total, on Claude Code 2.1.84, macOS The person who filed it. Self reported.
2026-03-25
(closed 2026-03-29)
One user filing a bug, now closed Skills listed as disabled still consumed context tokens The person who filed it. Self reported.

Two of those rows are worth reading twice. Rows three and six say the same thing from different directions: a skill you are not using still costs you something, in idle CPU in one case and in context tokens in the other. The unit differs, the conclusion does not.

Who should not use Claude Code skills

  • Anyone whose work is single step. If your request is read this file, or fix this function, the loader will usually answer directly and the skill will never open. You get the overhead without the behaviour.
  • Anyone who needs the same output twice. A skill is a prompt. The same skill on the same input does not have to produce the same result, and it will not after a model update. If you need reproducible output, you need a script, not a skill.
  • Anyone on Windows who will not change the execution policy. Any skill that ships a PowerShell file is dead until you do. There is no per skill workaround.
  • Anyone who installs third party skill bundles without reading them. 13.4% of the skills in the audit above carried a critical finding. Installing a collection of twenty without opening them is twenty chances.
  • Anyone running forty or more skill directories on a machine they care about. Idle CPU scaled with the count in the measurement above. If the fan is already audible, adding skills makes it worse and nothing you do inside a skill fixes it.
  • Anyone who edits SKILL.md during a session and expects it to take. You will lose an afternoon. It does not hot reload.
  • Anyone who wants a guarantee that a skill was followed. There is no enforcement layer. The confirmation line in step eleven of the setup is a convention you add yourself, not a feature.

Where it collapses

Three situations reliably break a setup that was working yesterday.

A model swap. Every trigger rate on this page was measured against one model on one build. Change either and the numbers move, including the ones you tuned a description against.

An upgrade. The behaviour in the two still open issues above is version specific. Pin your version and write it down, or you will not be able to tell an upgrade regression from your own mistake.

A long session. The longer a session runs, the more likely it is holding a stale copy of a skill you have since fixed. Restart rather than debug.

What a skill costs before it ever runs

Everything above is about getting a skill to fire. This part is about what you pay while it sits there doing nothing, and it is the reason the advice on this page keeps coming back to having fewer of them.

A skill directory is scanned whether or not the skill is used. In the September measurement above, the cost was about 45 syscalls per second and about 0.07 to 0.1% of one core for each directory, and it did not depend on how large the directory was. In the same report, one skill directory holding 594 files and 4 MB measured 1.8% CPU and 486 operations per second, while the remaining skill directories together measured 3.8% and 1,965. The scanning is per directory, not per file. Those two figures are from separate readings inside one bug report, so read them as the shape of the problem rather than as a tidy sum.

The same shape shows up on the token side. 43 skills silently present in a session measured about 3,950 tokens before anyone asked for anything, and skills marked disabled were still counted. A skill you switched off is still a skill you are paying for.

The practical rule falls out of those two rows without any interpretation: reduce the number of skill directories, not the size of any one of them. Consolidating five small skills into one skill with five sections costs you less than it looks like it should, and splitting one large skill into five costs you more.

And audit what you install before you install it. The registry numbers at the top of the dated table are from a single vendor's scan and should be read as one measurement, not as a rate, but 76 skills confirmed malicious by human review is not a rounding error in anyone's book.