Yeachan-Heo/oh-my-codex · error · Error

${filePath} has invalid YAML frontmatter on line ${index + 2

Error message

${filePath} has invalid YAML frontmatter on line ${index + 2}: ${trimmed}

What it means

Inside the frontmatter block, every non-comment, non-indented line must match 'key: value'. A line that does not match this simple single-line mapping syntax is reported with its 1-based file line number (index + 2 accounts for the opening fence and 0-based index).

Source

Thrown at src/cli/setup.ts:2269

	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}`,
			);
		}

		const [, key, rawValue] = match;
		if (!rawValue.trim()) continue;

		const parsedValue = parseSkillFrontmatterScalar(rawValue, key, filePath);
		if (key === "name") name = parsedValue;
		if (key === "description") description = parsedValue;
	}

	if (!name) {
		throw new Error(`${filePath} is missing a non-empty frontmatter "name"`);
	}
	if (!description) {
		throw new Error(
			`${filePath} is missing a non-empty frontmatter "description"`,

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Go to the reported line number in the named file and fix or remove it
  2. Keep frontmatter to flat single-line key/value pairs only
  3. Move complex metadata out of frontmatter into the body or code
  4. Lint with parseSkillFrontmatter before shipping

Example fix

# before
---
name: my-skill
tags:
  - one
  - two
description: d
---
# after
---
name: my-skill
description: d
tags: one,two
---
Defensive patterns

Strategy: validation

Validate before calling

const lines = frontmatterBlock.split(/\r?\n/);
for (const [i, l] of lines.entries()) {
  const t = l.trim();
  if (!t || t.startsWith("#") || /^\s/.test(l)) continue;
  if (!/^[A-Za-z0-9_-]+:(.*)$/.test(l)) throw new Error(`bad frontmatter line ${i + 2}: ${t}`);
}

Try / catch

try { parseSkillFrontmatter(content); } catch (e) { if (e instanceof Error && e.message.includes("invalid YAML frontmatter on line")) { const ln = Number(e.message.match(/line (\d+)/)?.[1]); fixLine(ln); } else throw e; }

Prevention

When it happens

Trigger: Lines like '- item' (sequences), 'nested:' followed by indented children later failing, 'key value' without a colon, or tabs/colons in odd places that break the key pattern [A-Za-z0-9_-]+:.

Common situations: Authors using full YAML features (lists, nested maps) that the minimal parser does not support, stray prose inside frontmatter, or duplicated malformed keys.

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


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/a506007bd2058920. Report an issue: GitHub.