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
- Read the embedded parse error and fix the YAML at the indicated line
- Recover content from the .broken-* backup the loader created next to the file, fix it, and replace the file
- Validate the YAML with a linter before saving
- 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
- Lint settings.yaml with a YAML parser before saving
- Use spaces, never tabs, for YAML indentation
- After version upgrades, check the changelog for settings schema changes
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
- Provider request limits must be positive numbers: ${invalidP
- Config overlay must be a YAML mapping: ${filePath}
- Limit must be a positive number.
- Invalid record JSON for ${path}
- Invalid agent field: ${filePath}\n${content}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3194824ce70f7f1a.
Report an issue: GitHub.