can1357/oh-my-pi · error
Settings config was invalid before locking and is now missin
Error message
Settings config was invalid before locking and is now missing: ${filePath}; another process may have moved it aside What it means
Thrown while reloading settings under a file lock: the settings YAML was determined invalid in an earlier pass, but when the loader re-acquires the lock and re-reads the file it has vanished (kind === "missing") and rejectMissing was requested. The library refuses to silently proceed because the invalid file may have been moved aside by a concurrent process, and overwriting/ignoring could lose user data.
Source
Thrown at packages/coding-agent/src/config/settings.ts:1451
const loaded = await this.#loadYamlIfPresentForWriteLocked(filePath, writePath, true);
return loaded.settings;
});
}
/**
* Read a YAML settings file while its write lock is held. Invalid files are
* moved aside before reporting failure, so a later write can never truncate
* the only copy of the user's configuration.
*/
async #loadYamlIfPresentForWriteLocked(
filePath: string,
writePath: string,
rejectMissing = false,
): Promise<LockedYamlLoadResult> {
let result = await this.#loadYamlIfPresent(writePath);
const generation = yamlGenerationFromLoadResult(result);
if (result.kind === "missing" && rejectMissing) {
throw new Error(
`Settings config was invalid before locking and is now missing: ${filePath}; another process may have moved it aside`,
);
}
if (result.kind === "invalid") {
result = await this.#quarantineInvalidYamlLocked(writePath, result);
this.#quarantinedYamlTargets.set(filePath, writePath);
}
return {
settings: this.#unwrapYamlLoadResult(filePath, result),
generation,
};
}
async #quarantineInvalidYamlLocked(
filePath: string,
result: Extract<YamlLoadResult, { kind: "invalid" }>,
): Promise<Extract<YamlLoadResult, { kind: "invalid" }>> {
const backupPath = `${filePath}.broken-${Date.now()}-${process.pid}-${randomUUID()}`;View on GitHub (pinned to 9690622007)
Solutions
- Re-run the command — the file state has settled and a fresh load will use defaults or the restored file
- Check for leftover *.broken-* backup files next to settings.yaml and restore/re-merge them
- Avoid running multiple processes that rewrite the same settings file simultaneously
Defensive patterns
Strategy: retry
Try / catch
try { await settings.load(); } catch (e) {
if (String(e).includes('now missing')) {
await Bun.sleep(250);
await settings.load(); // state has settled after the concurrent quarantine
} else throw e;
} Prevention
- Avoid running multiple omp processes that rewrite the same settings file at once
- Look for *.broken-* backups next to settings.yaml when this occurs
- Use a single settings writer process or serialize settings writes
When it happens
Trigger: Two processes concurrently loading/saving settings.yaml; process A quarantines (renames) the invalid file while process B, which had already classified it as invalid, reopens under lock and finds it gone with rejectMissing=true.
Common situations: Multiple omp instances (TUI + worker/SDK) sharing the same settings file; an editor or sync tool deleting the file mid-flight; race between quarantine renames.
Related errors
- Settings config is invalid and could not be moved aside: ${f
- Failed to read settings config ${filePath}: ${String(result.
- native spelling thread stopped
- Agent is already processing. Use steer() or followUp() to qu
- Failed to open auth database at '${dbPath}' after ${maxAttem
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/271a6b60fde1992d.
Report an issue: GitHub.