can1357/oh-my-pi · error · Error

Settings config is invalid: ${filePath}${result.backupPath ?

Error message

Settings config is invalid: ${filePath}${result.backupPath ? ` (moved to ${result.backupPath})` : ""}: ${String(result.error)}

What it means

Thrown when the settings YAML loads with kind === "invalid": the file exists and is readable but fails parsing/schema validation. Before throwing, the loader quarantines the broken file by renaming it to <path>.broken-<timestamp>-<pid>-<uuid> and reports the backup location plus the parse error. Settings are strict — an invalid file is never silently ignored for the main config.

Source

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

				`Settings config is invalid and could not be moved aside: ${filePath}; refusing to overwrite it: ${String(error)}`,
			);
		}
		logger.warn("Settings: moved invalid config aside", {
			path: filePath,
			backupPath,
			error: String(result.error),
		});
		return { ...result, backupPath };
	}

	#unwrapYamlLoadResult(filePath: string, result: YamlLoadResult): RawSettings | null {
		switch (result.kind) {
			case "missing":
				return null;
			case "loaded":
				return result.settings;
			case "invalid":
				throw new Error(
					`Settings config is invalid: ${filePath}${result.backupPath ? ` (moved to ${result.backupPath})` : ""}: ${String(result.error)}`,
				);
			case "unreadable":
				throw new Error(`Failed to read settings config ${filePath}: ${String(result.error)}`);
		}
	}

	async #readExistingMainYaml(quarantineInvalid: boolean): Promise<MainYamlReadResult> {
		if (!this.#configPath) return { settings: null, configPath: null };
		for (const filename of MAIN_CONFIG_FILENAMES) {
			const configPath = path.join(this.#agentDir, filename);
			const loaded = quarantineInvalid
				? await this.#loadYamlIfPresentForStartup(configPath)
				: this.#unwrapYamlLoadResult(configPath, await this.#loadYamlIfPresent(configPath, false));
			if (loaded) return { settings: loaded, configPath };
		}
		return {
			settings: null,

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the embedded parse error and fix the YAML at the indicated line
  2. Recover content from the .broken-* backup the loader created next to the file, fix it, and replace the file
  3. Validate the YAML with a linter before saving
  4. If the schema changed after an upgrade, migrate keys per the changelog

Example fix

// before (settings.yaml)
settings:
	theme: dark
// after (tabs are invalid YAML indentation)
settings:
  theme: dark
Defensive patterns

Strategy: try-catch

Validate before calling

async function yamlParses(path) {
  try { Bun.YAML.parse(await Bun.file(path).text()); return true; } catch { return false; }
}

Try / catch

try { const s = await loadSettings(); } catch (e) {
  if (String(e).startsWith('Settings config is invalid')) {
    // recover from the .broken-* backup named in the message, fix, retry
    const m = String(e).match(/moved to ([^)]+)\)/);
    logger.error('Settings YAML invalid; backup at', { backup: m?.[1] });
  } else throw e;
}

Prevention

When it happens

Trigger: Reading settings.yaml that contains malformed YAML (bad indentation, tabs, unbalanced quotes) or content failing the settings schema (wrong types for known keys).

Common situations: Hand-editing YAML and breaking indentation; pasting JSON5/JSON into a file that needs stricter YAML; a newer/older version changed the schema; merge-conflict markers left in the file.

Related errors


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