Yeachan-Heo/oh-my-codex · error · Error
${filePath} must start with YAML frontmatter containing non-
Error message
${filePath} must start with YAML frontmatter containing non-empty name and description fields What it means
parseSkillFrontmatter requires the file to begin with a '---' delimited YAML frontmatter block containing at least name and description. If the regex /^---\r?\n([\s\S]*?)\r?\n---/ does not match, the file is rejected before any field parsing.
Source
Thrown at src/cli/setup.ts:2252
return unquoted;
}
const unquoted = trimmed.replace(/\s+#.*$/, "").trim();
if (!unquoted) {
throw new Error(`${filePath} frontmatter "${key}" must not be empty`);
}
return unquoted;
}
export function parseSkillFrontmatter(
content: string,
filePath = "SKILL.md",
): SkillFrontmatterMetadata {
const frontmatterMatch = content.match(
/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/,
);
if (!frontmatterMatch) {
throw new Error(
`${filePath} must start with YAML frontmatter containing non-empty name and description fields`,
);
}
let name: string | undefined;
let description: string | undefined;
const lines = frontmatterMatch[1].split(/\r?\n/);
for (const [index, rawLine] of lines.entries()) {
const line = rawLine.trimEnd();
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) continue;
if (/^\s/.test(rawLine)) continue;
const match = line.match(/^([A-Za-z0-9_-]+):(.*)$/);
if (!match) {
throw new Error(
`${filePath} has invalid YAML frontmatter on line ${index + 2}: ${trimmed}`,View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Start the file with '---' on line 1, add the fields, close with a second '---'
- Ensure both fences begin at column 0 with no leading whitespace
- Include non-empty name and description fields inside the block
- Normalize line endings (CRLF is tolerated, stray BOM is not — remove BOM)
Example fix
# before # My Skill Does things. # after --- name: my-skill description: Does things. --- # My Skill Does things.
Defensive patterns
Strategy: validation
Validate before calling
const hasFences = content.startsWith("---") && /^---\r?\n[\s\S]*?\r?\n---/.test(content);
if (!hasFences) throw new Error("missing or misplaced frontmatter fences"); Type guard
const startsWithFrontmatter = (c: string): boolean => /^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/.test(c);
Try / catch
try { parseSkillFrontmatter(content); } catch (e) { if (e instanceof Error && e.message.includes("must start with YAML frontmatter")) { /* add --- fences at column 0 with name and description */ } else throw e; } Prevention
- Start every SKILL.md with a --- fence at column 0
- Strip BOM bytes before parsing
- Include non-empty name and description in the block
When it happens
Trigger: SKILL.md missing the opening '---' fence, having text before it, using '···' or other delimiters, or missing the closing fence so the block never terminates.
Common situations: Writing a plain markdown file and forgetting frontmatter entirely, Windows line-ending mixups, or fences indented by spaces (must start at column 0).
Understand the failure class
Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.
Related errors
- ${filePath} has invalid YAML frontmatter on line ${index + 2
- ${filePath} frontmatter "${key}" must not be empty
- ${filePath} frontmatter "${key}" must be a single-line strin
- ${filePath} frontmatter "${key}" has an unterminated quoted
- ${filePath} is missing a non-empty frontmatter "name"
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/1b2fee9dd7cd9708.
Report an issue: GitHub.