can1357/oh-my-pi · error · Error

Failed to parse config overlay ${filePath}: ${String(error)}

Error message

Failed to parse config overlay ${filePath}: ${String(error)}

What it means

The Settings loader parses config overlay files as YAML. When YAML.parse throws on the file's content, it wraps the failure with the file path and the underlying parser message so you know which overlay is malformed and why. This is a data-validation guard, not a runtime failure.

Source

Thrown at packages/coding-agent/src/config/settings.ts:1597

	 * missing or malformed files are hard errors so a typo'd path cannot
	 * silently fall back to the persistent settings.
	 */
	async #loadOverlayYaml(filePath: string, captureLegacyChangelogVersion = true): Promise<RawSettings> {
		let content: string;
		try {
			content = await Bun.file(filePath).text();
		} catch (error) {
			throw new Error(
				isEnoent(error)
					? `Config overlay not found: ${filePath}`
					: `Failed to read config overlay ${filePath}: ${String(error)}`,
			);
		}
		let parsed: unknown;
		try {
			parsed = YAML.parse(content);
		} catch (error) {
			throw new Error(`Failed to parse config overlay ${filePath}: ${String(error)}`);
		}
		if (parsed === null || parsed === undefined) return {};
		if (typeof parsed !== "object" || Array.isArray(parsed)) {
			throw new Error(`Config overlay must be a YAML mapping: ${filePath}`);
		}
		return this.#migrateRawSettings(parsed as RawSettings, captureLegacyChangelogVersion);
	}

	async #migrateFromLegacy(): Promise<void> {
		if (!this.#configPath) return;

		let settings: RawSettings = {};
		let migrated = false;

		// 1. Migrate from settings.json
		const settingsJsonPath = path.join(this.#agentDir, "settings.json");
		try {
			const parsed: unknown = JSONC.parse(await Bun.file(settingsJsonPath).text());

View on GitHub (pinned to 9690622007)

Solutions

  1. Open the file named in the message and fix the YAML syntax at the reported line (the wrapped String(error) includes the parser's line/column).
  2. Validate the file first with a YAML linter or `bun -e 'require("yaml").parse(require("fs").readFileSync("<file>","utf8"))'`.
  3. Replace tabs with spaces and confirm consistent 2-space indentation.
  4. If the file is intentionally another format, rename it to the correct extension or convert it to YAML.

Example fix

// before (settings.overlay.yaml)
agent:
	defaultModel: gpt-5
  tools:
   -write
// after
agent:
  defaultModel: gpt-5
  tools:
    - write
Defensive patterns

Strategy: validation

Validate before calling

import YAML from "yaml";
import { readFile } from "node:fs/promises";
try {
  YAML.parse(await readFile(overlayPath, "utf8"));
} catch (e) {
  console.error(`Fix YAML syntax in ${overlayPath}:`, e.message);
  process.exit(1);
}

Try / catch

try {
  await settings.load();
} catch (e) {
  if (String(e.message).startsWith("Failed to parse config overlay")) {
    // surface path+parser detail to the user, fall back to defaults
  } else throw e;
}

Prevention

When it happens

Trigger: Loading a config overlay file whose bytes are not valid YAML — e.g. inconsistent indentation, unbalanced brackets/quotes, tabs for indentation, or a file in another format (JSON5/TOML) handed to a .yaml path.

Common situations: Hand-editing settings.yaml and leaving a dangling colon or wrong indent level; pasting JSON with tabs; a dotfile-sync tool merging conflicting versions; a template rendered with unfilled placeholders like ${VAR}.

Understand the failure class

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/671476d276eee487. Report an issue: GitHub.