A skill that never runs usually has nothing wrong with its syntax. It loads, it sits in the list, and it is never chosen — because the description does not say when it applies, or says it in words nobody would use. That failure is silent by design: there is no error, no warning, and no signal that anything is wrong. This linter reads the file the way the loader does, reports anything malformed, and then spends most of its attention on the description: whether it names a trigger, whether it is long enough to match on, and whether it opens by restating that it is a skill. Fields the loader ignores are called out too, since a typo in a key name looks exactly like a working file.
Features
Reads the frontmatter with a real YAML parser and reports where it fails
Flags fields the loader does not read, which is what a typo in a key looks like
Checks the description for a trigger clause and for length
Reports the description's character count against the limit
Checks the instructions for the length below which they rarely help
A readiness score with errors weighted above suggestions
Drop a file in, or paste it
A deliberately broken example to see what it catches
How to use the Skill Linter
Drop in a SKILL.md, or paste its contents
Read the findings, worst first
Fix the description if it is flagged — that is the one that matters
Re-check until the score is clean
Example
Input
description: Helps with PDFs
Output
Warning: says what the skill is, but not when to use it
The most common reason a skill is never chosen.
Common errors & troubleshooting
It says there is no frontmatter, but there clearly is. — The three hyphens have to be the very first line — no blank line, no comment, nothing above them.
The YAML fails to parse on a long description. — A description containing a colon followed by a space has to be quoted, or YAML reads it as another key.
It flags a field I use deliberately. — Unknown fields are reported as notes, not errors. The loader ignores them; the note is there because a misspelled key looks identical to a working one.
The score stays low with no errors listed. — Warnings cost points too. The usual pair is a description with no trigger clause and instructions too short to change anything.
Frequently asked questions
Why does my skill load but never get chosen?
The description is matched against the task, so if it only describes the subject — “works with spreadsheets” — there is nothing to match a request against. Adding a clause naming the situation, the file types, or the words a person would use is usually the whole fix.
What counts as a trigger clause?
Anything that names the moment the skill applies: “Use when the user asks to…”, “Whenever a migration file changes…”, “For tasks involving…”. The linter looks for that shape and warns when none is present.
Is a long description bad?
Not in itself — there is a generous limit, and the count is shown. What hurts is a long description that still never says when to use the skill, which is a surprisingly common combination.
Can I lint a skill I did not write?
That is a good use of it. Dropping in a skill from elsewhere shows immediately whether its description will compete with your own skills, and whether it declares tools you did not expect.
Does a clean result guarantee the skill works?
No. It means the file will load and the description has the shape that gets matched. Whether the instructions are any good is a judgement no linter makes.
Related tools
Skill Builder — Write a SKILL.md with the frontmatter checked as you type.
Subagent Builder — Build a subagent definition file with its tools and model set.
System Prompt Linter — Find contradictions, dead instructions and unfilled placeholders in a prompt.
Tool Schema Checker — Paste a tool definition and find out why it is rejected or mis-called.