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

  1. Re-run the command — the file state has settled and a fresh load will use defaults or the restored file
  2. Check for leftover *.broken-* backup files next to settings.yaml and restore/re-merge them
  3. 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

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


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