Common SKILL.md mistakes and how to avoid them
The mistakes skillmd lint catches most often in SKILL.md files, why each one costs points, and the exact fix for each.
Contents
- Mistake 1: a missing or too-terse description
- Mistake 2: no license declared
- Mistake 3: a stub body with no headings
- Mistake 4: a name that’s too long or doesn’t match its directory
- Mistake 5: a description so long it rejects the whole file
- Mistake 6: tripping the security scan with ordinary documentation
- Mistake 7: frontmatter that doesn’t start at byte zero
- Run lint before you publish
Most SKILL.md problems are not exotic. They are the same handful of mistakes repeated across thousands of files: a description that says nothing, a body that is three sentences long, a name that does not match its folder. skillmd lint catches all of them before you publish. This post walks through each one, the rule that flags it, and the fix.
Every skill starts at a quality score of 100. Errors cost far more than warnings, and anything the security scan flags costs more still. None of these mistakes are fatal alone, but they stack, and a file with three or four of them looks worse than the sum of its parts.
Mistake 1: a missing or too-terse description
The description field is what an agent reads to decide whether your skill is relevant before it opens the body. Leave it out entirely and you hit SK003, an error: description is required, and the file fails lint outright.
The harder case is a description that exists but says nothing. Lint warns under SK010 when the description is shorter than about 20 characters. “Handles PDFs” clears the character count and still tells an agent almost nothing about when to use the skill.
Fix: write one sentence naming the input, the action, and the output. “Extracts text and tables from PDF files using pdfplumber, with page-range and layout options” tells an agent when to reach for it. Run skillmd rules SK010 to see the rule text while editing.
Mistake 2: no license declared
SK011 is a warning, so it is easy to forget. No license field in frontmatter costs you real ground on the quality score for something that takes one line to fix.
license: MIT
Use a real SPDX identifier: MIT, Apache-2.0, ISC, whatever applies. Anyone installing the skill wants to know the terms without opening an issue to ask.
Mistake 3: a stub body with no headings
SK020 fires when the body is under roughly 200 characters, a placeholder someone meant to fill in later. SK021 fires when the body has no Markdown heading at all. Unstructured prose might contain real instructions, but an agent has nothing to anchor on.
Fix both by treating the body as the actual instructions, not a footnote:
## Usage
Run this skill when a user needs structured text or table data pulled out of a PDF instead of just raw text.
## Steps
1. Load the PDF with the extraction library.
2. Extract text page by page, or target a page range if specified.
3. For tables, return structured rows rather than flattened text.
A couple of headings and a real steps list clear both warnings.
Mistake 4: a name that’s too long or doesn’t match its directory
The name field has a hard cap: over 120 characters trips SK002, an error. Rare, but it happens when someone pastes a full sentence into name instead of a short identifier.
More common is SK040, a warning: the slugified form of name does not match the directory the skill lives in. If your folder is pdf-extract but name reads PDF Extraction Tool, lint flags the mismatch. It still works, since the runtime does not require the two to agree, but a mismatch usually means the skill was renamed once and left half-updated.
Fix: keep name short and matched to the directory name. If you rename one, rename the other.
Mistake 5: a description so long it rejects the whole file
This is the opposite failure from mistake 1. SK003 also covers the upper bound: over 1024 characters in description and the entire file is rejected, not trimmed to fit. This happens when someone pastes an entire usage guide into the frontmatter field instead of the body. The description is a one-sentence summary for relevance matching, not step-by-step instructions. If you are writing more than two or three sentences there, move the rest into the body under a heading.
Mistake 6: tripping the security scan with ordinary documentation
The security scan flags patterns in the body that look like reading secrets, running scripts, or making network calls. It cannot tell the difference between a skill that actually shells out to a script and one that merely explains, in prose, what a shell command does.
All three flags cost real ground on the score, and the riskier the behavior, the more it costs. Writing “pass your API key as an environment variable,” or including a fenced shell block with curl in it, can trigger these flags even when the skill never runs anything itself.
If your score is lower than expected, check the body for words like “token,” “secret,” or “API key,” and for shell, Python, or JS code fences. Keep real examples if the skill genuinely does that work. For purely explanatory text, describe what the operation does instead of writing it as a literal command a machine would run.
Mistake 7: frontmatter that doesn’t start at byte zero
This has no rule ID of its own, since it is a parse failure rather than a lint warning, but it is common enough to call out. The frontmatter block must open with --- as the very first bytes of the file. A leading blank line or a byte order mark from an editor defaulting to UTF-8-with-BOM breaks parsing before lint reaches the numbered rules.
If skillmd lint reports a parse error on a file that looks fine, check the first line for invisible characters. Re-saving as plain UTF-8 without a BOM usually clears it.
Run lint before you publish
All of this is checkable locally before a skill reaches the registry:
skillmd lint my-skill/SKILL.md
If a rule ID in the output is unfamiliar, skillmd rules SK010 (or any other ID) prints that rule’s description so you are not guessing at what triggered it.
The scoring rewards fixing errors first: an error costs you far more than a warning, and a security-scan flag can cost more than either. A file with a missing license and a mismatched name will score noticeably lower than a clean one; add a missing-description error and a stub-body warning and it drops further still. None of these are hard to fix once you know which rule is complaining, which is the entire point of running lint before you publish instead of after.