AIPM
Theme

Plain-English guide

Fix: SKILL.md must start with YAML frontmatter (---)

If a skill is ignored, SKILL.md must open with --- YAML. Required fields, limits, and the fix for Claude Code, Codex, and Cursor.

Published September 25, 2026. Last reviewed October 7, 2026. Facts checked against official docs on September 25, 2026.

Short answer

If a skill is ignored, the usual fix is the first lines of the file: SKILL.md must start with YAML frontmatter between --- lines. name and description are required: the open Agent Skills spec, Cursor and Codex all require them, and AIPM documents them as required. name is up to 64 lowercase letters, numbers and hyphens and matches the folder; description is up to 1,024 characters. Optional spec fields are license, compatibility, metadata and allowed-tools. Claude Code adds fields such as when_to_use, disable-model-invocation, context and paths. Need a starting file? Use a SKILL.md template.

The two required fields, as the Agent Skills spec defines them (checked 25 September 2026).
FieldRequiredLimitExample
nameYes1–64 characters: a-z, 0-9 and -; no leading, trailing or double hyphen; same as the folder namecode-review
descriptionYes1–1,024 characters; say what the skill does and when to use itReview code changes for bugs… Use when the user asks for a review.

Words used in this guide

  • AIPM: a tool that installs and updates reusable AI instructions.
  • Package: a named group of files that people can install and update together.
  • Git: a tool that records file changes so people can review or undo them.
  • Config: settings that tell a tool how to work.
  • MCP: a standard way for an AI tool to connect to other tools and information.

What this means

A minimal SKILL.md that works everywhere

Put --- on the very first line, then key: value pairs, then a closing ---. The Markdown instructions go after it. This file uses only the two required fields, so the Agent Skills spec, Claude Code, claude.ai uploads, Cursor and Codex all accept it. More starting files: SKILL.md templates and examples. Not sure where to save the file? See where Claude skills are stored.

.claude/skills/code-review/SKILL.md

---
name: code-review
description: Review code changes for bugs, security risks and missing tests. Use when the user asks for a review of a diff or pull request.
---

# Code review

1. Read the changed files and nearby tests.
2. Report problems that change behavior, most serious first.

The portable fields (Agent Skills spec)

The Agent Skills specification defines six frontmatter fields. Use only these if the skill must run in more than one tool or be uploaded to claude.ai.

Valid names from the spec: pdf-processing, data-analysis, code-review. Invalid: PDF-Processing (uppercase), -pdf (leading hyphen), pdf--processing (consecutive hyphens).

The spec also recommends keeping SKILL.md under 500 lines and the instructions under 5,000 tokens; only name and description (about 100 tokens) load at startup. Keep file references one level deep from SKILL.md.

Check a folder against the spec with the skills-ref reference library:

Agent Skills spec fields (agentskills.io/specification, checked 25 September 2026).
FieldRequiredConstraintExample
nameYes1–64 characters; lowercase a-z, 0-9 and hyphens; must not start or end with -; no --; must match the parent folderpdf-processing
descriptionYes1–1,024 characters; what the skill does and when to use it, with keywords agents can matchExtract PDF text, fill forms, merge files. Use when handling PDFs.
licenseNoA license name or the name of a bundled license fileApache-2.0
compatibilityNo1–500 characters; only if the skill has environment requirementsRequires git, docker, jq, and access to the internet
metadataNoA map of string keys to string values; pick key names unlikely to clashauthor: example-org
allowed-toolsNo (experimental)Space-separated string of pre-approved tools; support varies by toolBash(git:*) Bash(jq:*) Read
skills-ref validate ./my-skill

How Claude Code reads frontmatter

Claude Code is more lenient than the spec. Per the Claude Code skills docs:

  • Every field is optional. Only description is recommended; without it, Claude uses the first non-empty line of the Markdown. name defaults to the folder name.
  • Frontmatter is read only when the opening --- is the first line of the file. Otherwise the whole file, markers included, is treated as instructions.
  • If the YAML doesn't parse, the skill still loads with no fields set: /skill-name works, but Claude can't match your description. Run claude --debug to see the parse error.
  • A field name must match exactly, hyphens included. An unknown field is ignored without an error.
  • Field names are lowercase and hyphenated, except when_to_use.
  • Booleans accept yes, no, on, off, 1 and 0 in any case, as well as true and false, from v2.1.218.
  • In a personal or project skill, name only sets the label in skill listings; the command you type comes from the folder name. In a plugin skill, name sets the last part of the command, such as /my-plugin:fancy.
  • Command files in .claude/commands/ accept the same fields except name and paths. See Claude Code skills vs slash commands.

Claude Code frontmatter fields

Every field Claude Code documents, with what it's for. All are optional.

Claude Code SKILL.md fields (code.claude.com/docs/en/skills, checked 25 September 2026; latest release 2.1.282).
FieldUse it for
nameLabel shown in skill listings. Defaults to the folder name
descriptionWhat the skill does and when to use it (recommended). Claude matches requests against it
when_to_useExtra trigger phrases or example requests, appended to description in the listing
argument-hintAutocomplete hint such as [issue-number] or [filename] [format]
argumentsNamed positional arguments for $name substitution; a space-separated string or YAML list
disable-model-invocationtrue = only you can run it with /name. Default false
user-invocablefalse = only Claude can run it; hidden from the / menu. Default true
allowed-toolsTools Claude may use without asking during the turn that invokes the skill. It pre-approves; it does not restrict
disallowed-toolsTools removed while the skill is active, until your next message
modelModel for the rest of the current turn, or inherit
effortlow, medium, high, xhigh or max; levels depend on the model
contextfork runs the skill in a forked subagent context (skills vs subagents)
agentSubagent type to use with context: fork, such as Explore
backgroundWith context: fork only: false waits for the result in the same turn. Default true. v2.1.218+
hooksHooks registered when the skill is invoked
pathsGlob patterns; Claude loads the skill automatically only when working with matching files
shellbash (default) or powershell for inline shell commands
metadataYour own key-value data. Claude Code doesn't act on it and drops a value that isn't a map
licenseSpec field; accepted, not acted on
compatibilitySpec field, up to 500 characters; accepted, not acted on

Who can invoke a skill: invocation control

Two Claude Code fields decide whether you, Claude, or both can start a skill, and what sits in context.

disable-model-invocation: true also stops the skill being preloaded into subagents and, from v2.1.196, stops it running when a scheduled task fires with it as the prompt. Cursor supports the same field. Codex has no frontmatter field for this: set policy.allow_implicit_invocation: false in agents/openai.yaml instead.

From the Claude Code skills docs (checked 25 September 2026).
FrontmatterYou can invokeClaude can invokeIn context
(default)YesYesDescription always; full skill when invoked
disable-model-invocation: trueYesNoNothing until you invoke it
user-invocable: falseNoYesDescription always; full skill when invoked

Description length and the skill listing budget

Claude Code puts every skill's name and description in a listing so Claude knows what exists. The combined description and when_to_use text is cut at 1,536 characters per skill, so put the main use case first. The cap is configurable with the skillListingMaxDescChars setting.

  • The whole listing gets 1% of the model's context window. Raise it with skillListingBudgetFraction (for example 0.02) or set a fixed character count with SLASH_COMMAND_TOOL_CHAR_BUDGET.
  • When the listing is over budget, the skills you invoke least lose their descriptions first. Names always stay.
  • /doctor estimates the listing's cost; /skill-doctor finds skills worth turning off.
  • Codex caps its initial skills list at 2% of the context window, or 8,000 characters when the window is unknown, and shortens descriptions first.

Frontmatter for claude.ai uploads and the Skills API

claude.ai skill uploads, the Skills API and package_skill.py from anthropics/skills accept only the six spec fields: name, description, license, compatibility, metadata and allowed-tools. Any other field is a hard error, not a warning. The same applies when you enable a personal Claude Code skill for your claude.ai account (for Cowork, cloud sessions or routines), because that uploads it.

The Claude Help Center lists these other upload failures: the ZIP is too large, the folder name doesn't match the skill name, SKILL.md is missing, or the name or description has invalid characters.

Error text from the Claude Code docs

Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name

Cursor frontmatter

Cursor's skill format (Cursor docs) requires name (lowercase letters, numbers and hyphens, matching the parent folder) and description. Optional fields: paths (comma-separated string or list; the legacy globs field still works as a fallback), disable-model-invocation, icon and color (for Custom Modes; color is one of default, green, cyan, blue, purple, magenta, orange, yellow, red or brand), and metadata.

Cursor also reads skills from .claude/skills/ and .agents/skills/, so AIPM installs made with --target claude or --target codex work in Cursor. More: how to install Cursor skills.

Codex frontmatter and agents/openai.yaml

Codex requires name and description in SKILL.md (Codex docs). Display settings, invocation policy and tool dependencies go in an optional agents/openai.yaml next to it, not in frontmatter.

allow_implicit_invocation defaults to true. With false, Codex won't pick the skill on its own, but $skill still works. See Claude Code skills vs Codex skills for other differences.

my-skill/agents/openai.yaml

interface:
  display_name: "Optional user-facing name"
  short_description: "Optional user-facing description"
  icon_small: "./assets/small-logo.svg"
  icon_large: "./assets/large-logo.png"
  brand_color: "#3B82F6"
  default_prompt: "Optional surrounding prompt to use the skill with"

policy:
  allow_implicit_invocation: false

dependencies:
  tools:
    - type: "mcp"
      value: "openaiDeveloperDocs"
      description: "OpenAI Docs MCP server"
      transport: "streamable_http"
      url: "https://developers.openai.com/mcp"

One table: which fields work where

Each cell comes from that tool's own docs, checked 25 September 2026. "Not documented" means the tool's docs don't list the field, so don't rely on it there. For which tools read which files at all, see the AI agent file support table.

The safe rule: if a skill must run in several tools, or be uploaded to claude.ai, use only the six spec fields. Keep Claude Code-only fields in a copy that stays in .claude/skills/.

SKILL.md frontmatter support by tool. Error = upload or packaging fails.
FieldAgent Skills specClaude Codeclaude.ai upload / Skills APICursorCodex
nameRequiredOptional (defaults to folder name)AllowedRequiredRequired
descriptionRequiredRecommendedAllowedRequiredRequired
licenseOptionalAccepted, not acted onAllowedNot documentedNot documented
compatibilityOptional (≤500 chars)Accepted, not acted on (≤500)AllowedNot documentedNot documented
metadataOptional (string map)Optional, not acted onAllowedOptionalNot documented
allowed-toolsOptional, experimentalOptional (pre-approves)AllowedNot documentedNot documented
when_to_useNot in specOptionalErrorNot documentedNot documented
argument-hint, argumentsNot in specOptionalErrorNot documentedNot documented
disable-model-invocationNot in specOptionalErrorOptionalUse agents/openai.yaml policy
user-invocableNot in specOptionalErrorNot documentedNot documented
disallowed-toolsNot in specOptionalErrorNot documentedNot documented
model, effortNot in specOptionalErrorNot documentedNot documented
context, agent, backgroundNot in specOptionalErrorNot documentedNot documented
hooksNot in specOptionalErrorNot documentedNot documented
pathsNot in specOptionalErrorOptional (legacy globs accepted)Not documented
shellNot in specOptionalErrorNot documentedNot documented
icon, colorNot in specIgnored (unknown field)ErrorOptionalNot documented

Frontmatter errors and how to fix them

Match the symptom, then apply the fix.

The exact messages "must be a YAML mapping" and "missing frontmatter" aren't in the Claude Code, Cursor or Codex docs we checked, so this page doesn't say which tool prints them. A YAML mapping is simply a set of key: value pairs.

General YAML rules apply too: indent with spaces, never tabs, and quote a value that contains : or #, or that starts with [, { or *.

Common SKILL.md frontmatter problems and fixes.
SymptomWhereCauseFix
Unexpected key(s) in SKILL.md frontmatterclaude.ai upload, Skills API, package_skill.pyA field outside the six spec fields, such as argument-hintRemove the field, or keep a separate Claude Code copy
Skill never triggers, or its fields are ignoredClaude Code--- isn't on line 1, or the YAML doesn't parse, so the skill loads with no fieldsPut --- on the first line and fix the YAML. Check with claude --debug and claude plugin validate .claude/skills (v2.1.233+)
Upload rejectedclaude.aiFolder name doesn't match name, SKILL.md missing, invalid characters, or ZIP too largeRename the folder to match name, keep SKILL.md at the top of the folder, and remove large files
Name rejected or skill not foundSpec, Cursorname differs from the folder, or has uppercase letters, spaces or --Use lowercase letters, numbers and single hyphens, and name the folder the same
Description cut shortClaude CodeOver 1,536 characters with when_to_use, or the listing is over budgetLead with the main use case; see the listing budget section above
"Must be a YAML mapping" or "missing frontmatter"Validators (tool varies)The block between --- lines isn't key: value pairs (for example a list or plain text), or the file doesn't start with ---Start the file with --- and write one key: value pair per line
Tool still asks for permission, or a tool you wanted blocked still runsClaude Codeallowed-tools pre-approves tools for one turn; it never blocks toolsUse disallowed-tools to remove tools while the skill runs
Claude runs the skill when you didn't askClaude Code, CursorDescription matches too many requestsMake the description more specific, or set disable-model-invocation: true

Complete examples

Three copy-ready files. The first is safe everywhere; the other two use Claude Code-only fields, so don't upload them to claude.ai as they are.

1. Portable (spec fields only)

---
name: release-notes
description: Write release notes from merged pull requests. Use when the user asks for release notes, a changelog entry or upgrade notes.
license: MIT
metadata:
  owner: platform-team
---

2. Claude Code: manual-only skill with arguments

---
name: fix-issue
description: Fix a GitHub issue end to end and open a pull request.
when_to_use: Use when the user gives an issue number and asks for a fix.
argument-hint: "[issue-number]"
disable-model-invocation: true
allowed-tools: Bash(gh *) Read Grep
paths: "src/**/*.ts"
---

Fix issue $ARGUMENTS: read it with gh, find the cause, add a test, then fix it.

3. Claude Code: forked research skill

---
name: deep-research
description: Research a topic thoroughly in the codebase
context: fork
agent: Explore
---

Research $ARGUMENTS thoroughly and summarize findings with file references.

Publish a skill with AIPM

AIPM documents name and description as required for every skill you publish. AIPM installs a skill into a folder named after the package's short name (@team/code-review → .claude/skills/code-review/ with --target claude, .agents/skills/code-review/ with --target codex), so set name to that short name to keep the spec and Cursor happy. AIPM copies SKILL.md as published and doesn't rewrite frontmatter for each tool.

Check the frontmatter yourself before you run aipm publish validate. Next steps are in the publishing guide; starting files are on the templates page; a full walkthrough is in how to create an Agent Skill; to get the skill to teammates, see how to share Claude skills with your team.

npm install -g @aipm-registry/cli
aipm skill init --name @team/code-review --template code-review
cd code-review
# add frontmatter (name, description) to the generated SKILL.md if it isn't there, then:
aipm publish add .
aipm publish validate

Simple steps

  1. Put --- on the first line of SKILL.md.
  2. Add name: lowercase letters, numbers and hyphens, the same as the folder name.
  3. Add description: what the skill does and when to use it, under 1,024 characters.
  4. Add optional spec fields (license, compatibility, metadata, allowed-tools) only if you need them.
  5. Add Claude Code-only fields only to copies that stay in Claude Code.
  6. Close the block with --- and write the instructions below it.

Where to go next

If you want to try this in a real project, start with how to use AIPM and the command reference. If you want to share your own workflow, read the publishing guide.

FAQ

What fields are required in SKILL.md frontmatter?

name and description. The Agent Skills spec, Cursor and Codex require both, and AIPM documents both as required. Claude Code alone treats every field as optional: it recommends description, and name defaults to the folder name.

How long can a skill description be?

Up to 1,024 characters in the Agent Skills spec. Claude Code also cuts the combined description and when_to_use text at 1,536 characters in its skill listing.

What characters are allowed in a skill name?

Lowercase letters, numbers and hyphens, 1–64 characters, with no leading, trailing or double hyphens. The name must match the skill's folder.

Why does claude.ai say "Unexpected key(s) in SKILL.md frontmatter"?

Uploads and the Skills API accept only name, description, license, compatibility, metadata and allowed-tools. Remove Claude Code-only fields such as argument-hint or when_to_use.

Does allowed-tools restrict which tools a skill can use?

No. In Claude Code it pre-approves the listed tools for the turn that invokes the skill. To remove tools, use disallowed-tools.

How do I stop Claude from triggering a skill automatically?

Set disable-model-invocation: true. You can still run it yourself with /skill-name.

Where does Codex put skill settings like implicit invocation?

In an optional agents/openai.yaml file next to SKILL.md: set policy.allow_implicit_invocation to false. $skill still works.

Sources

Related guides