Resources · Claude Code skills

Claude Code says "SKILL.md must start with YAML frontmatter (---)": the exact fix

Claude Code throws this error when SKILL.md does not open with a --- delimited YAML block on line 1; add the block with name and description, close it with a second ---, and the skill loads. Below is the valid shape and every common way files fail it, each with a broken and a fixed example.

By Jonathan Dag, Founder & CEO·

The valid shape, in one block

Per Anthropic's documentation, "Every skill needs a SKILL.md file with two parts: YAML frontmatter between --- markers that tells Claude when to use the skill, and markdown content with the instructions Claude follows when the skill runs" (code.claude.com/docs/en/skills). Three rules cover the parser: the opening --- is line 1, a second bare --- closes the block, and the YAML between them is valid with at least name and description.

.claude/skills/monthly-revenue/SKILL.md
---
name: monthly-revenue
description: Use when asked about monthly revenue or revenue trends.
---

Instructions the agent follows when this skill runs.

The five ways files fail the check

The top search results for this error are issue threads that quote it without a root cause (for example VoltAgent/awesome-design-md#103 and nextlevelbuilder/ui-ux-pro-max-skill#399). In practice the failures reduce to five shapes.

1. The second --- delimiter is missing

Broken
---
name: monthly-revenue
description: Use when asked about monthly revenue.

Instructions start here.
Fixed
---
name: monthly-revenue
description: Use when asked about monthly revenue.
---

Instructions start here.

The block opens but never closes, so the parser reads the whole file as unterminated frontmatter and rejects it. Close the block with a second bare --- on its own line before the body.

2. A blank line (or anything) before the first ---

Broken
---
name: monthly-revenue
description: Use when asked about monthly revenue.
---
Fixed
---
name: monthly-revenue
description: Use when asked about monthly revenue.
---

The opening --- must be line 1, byte 1. A leading blank line, a stray heading, or an HTML comment above it all trigger the error. Delete everything above the opening delimiter so the file starts with the three dashes.

3. The file is saved as UTF-8 with BOM

Broken
<U+FEFF>---
name: monthly-revenue
description: Use when asked about monthly revenue.
---
Fixed
---
name: monthly-revenue
description: Use when asked about monthly revenue.
---

Invisible BOM bytes (EF BB BF) sit before the first dash, so line 1 no longer starts with ---. Common on Windows editors that default to UTF-8 with BOM. Re-save the file as UTF-8 without BOM (VS Code: "Save with Encoding" → UTF-8). Reported in openai/codex#13918.

4. The frontmatter is wrapped in a code fence

Broken
```yaml
---
name: monthly-revenue
description: Use when asked about monthly revenue.
---
```
Fixed
---
name: monthly-revenue
description: Use when asked about monthly revenue.
---

Pasted from a chat or a README, the block arrives wrapped in triple backticks, so line 1 is the fence, not the delimiter. Remove the surrounding fence; the raw file starts with the dashes themselves.

5. An unquoted colon inside a field value

Broken
---
name: monthly-revenue
description: Use when: revenue questions come up
triggers:
  - revenue: monthly
---
Fixed
---
name: monthly-revenue
description: "Use when: revenue questions come up"
triggers:
  - "revenue: monthly"
---

A colon followed by a space inside an unquoted value makes the YAML invalid, and some loaders surface that as the frontmatter error. Quote any value that contains a colon, or rephrase the value without one. Reported in openai/codex#8609.

Quick answers

Which frontmatter fields are required?

name and description. The description should start with "Use when" so the agent's routing layer can match prompts to the skill. Fields like triggers and must-read are optional extensions.

Where does Claude Code look for SKILL.md files?

Under .claude/skills/ at the repo root, one folder per skill, each holding a SKILL.md. The directory name becomes the command you type after /.

Why does my skill load but never trigger automatically?

That is the sibling failure: malformed YAML can load the body with empty metadata, so /skill-name works but routing has no description to match. Validate the frontmatter and check the description vocabulary.

Does the same format work outside Claude Code?

Yes. Claude Code skills follow the Agent Skills open standard, so the same SKILL.md shape is read by other tools, including Codex and Cursor setups that consume .agents/skills/.

More on how Chion builds and exports skills in the FAQ.

Or never hand-write the frontmatter again

If the skills you are writing wrap SQL, Chion's Claude SQL skills generator compiles your team's verified Postgres queries into SKILL.md files with valid frontmatter by construction: the delimiters, name, description, and triggers are emitted by the same deterministic pass every time, so this error never appears. The hand-authoring guide lives in Claude Code skills for SQL.