stablyai/orca · warning · Error
Codex hooks.json changed while Orca prepared its trust repai
Error message
Codex hooks.json changed while Orca prepared its trust repair
What it means
Thrown by assertHooksJsonGeneration when the raw bytes of the user's real-home hooks.json (or its resolved write path) changed between the initial read (readHooksJsonWithRaw) and the pre-write generation check. Orca snapshots the file, prepares an in-memory mutation, then re-reads on disk before writing; a concurrent external save (user's editor, another codex instance) invalidates the snapshot to avoid clobbering newer content with a stale parse.
Source
Thrown at src/main/codex/codex-real-home-hook-install.ts:81
function getRealHomeConfigTomlPath(): string {
return join(getSystemCodexHomePath(), 'config.toml')
}
/** Orca-side state dir; nothing extra is ever written into the user's ~/.codex. */
function getRealHomeHookStateDir(userDataPath: string): string {
return join(userDataPath, 'codex-real-home-hooks')
}
function assertHooksJsonGeneration(
hooksJsonPath: string,
hooksWritePath: string,
expectedRaw: string | null
): void {
const currentRaw = existsSync(hooksJsonPath) ? readFileSync(hooksJsonPath, 'utf-8') : null
if (currentRaw !== expectedRaw || resolveHooksJsonWritePath(hooksJsonPath) !== hooksWritePath) {
// Why: the pre-mutation RPC can overlap a user's editor save. Abort rather
// than atomically replacing a newer file with the stale parsed snapshot.
throw new Error('Codex hooks.json changed while Orca prepared its trust repair')
}
}
/**
* Ensures the real-home hook state matches the settings: installs and trusts
* the Orca status hook when enabled, sweeps it when opted out. Idempotent and
* synchronous (launch prep); repeat calls are cheap — an unchanged hooks.json
* write no-ops and a valid grant ledger skips the RPC session entirely.
* Never throws: any failure logs and leaves the host on the managed lane.
*/
export function ensureRealHomeCodexHookState(args: {
hooksEnabled: boolean
userDataPath: string
}): RealHomeCodexHookLane {
// Why: the grant client caches failed probes, but mutating and rolling back
// hooks.json before consulting it still adds synchronous work to every pane.
if (args.hooksEnabled && currentLane === 'unavailable' && Date.now() < installRetryAfterMs) {
return currentLaneView on GitHub (pinned to 1136503c6a)
Solutions
- Close editors/tools editing ~/.codex/hooks.json during launch, then retry — ensureRealHomeCodexHookState retries on the next pane.
- If using a hook-manager extension, pause it or coordinate so only one writer mutates hooks.json at a time.
- Confirm hooks.json is not a symlink whose target changes (resolveHooksJsonWritePath must be stable).
- Rely on the managed-home fallback: a failed install leaves currentLane='unavailable' and status still works.
- Re-enable real-home hooks after the external edit completes.
Defensive patterns
Strategy: retry
Validate before calling
// Minimize the window between snapshot and write; avoid long async gaps in writeHooks.
// Before install, warn the user if hooks.json mtime changed very recently:
import { statSync } from 'node:fs'
const mtimeMs = statSync(hooksJsonPath).mtimeMs
if (Date.now() - mtimeMs < 2000) {
// likely being edited; defer the install to the next pane launch
} Type guard
function isHooksJsonGenerationError(error: unknown): boolean {
return error instanceof Error && error.message === 'Codex hooks.json changed while Orca prepared its trust repair'
} Try / catch
try {
ensureRealHomeCodexHookState({ hooksEnabled: true, userDataPath })
} catch (error) {
if (isHooksJsonGenerationError(error)) {
// non-fatal: managed lane continues; retry on next pane launch
currentLane = 'unavailable'
} else throw error
} Prevention
- Avoid editing ~/.codex/hooks.json while Orca is launching.
- The install is retried on the next pane; no manual action needed for transient races.
- Keep hooks.json a real file (stable symlink target), not a swapping symlink.
- Coordinate hook managers so only one writer mutates hooks.json at a time.
When it happens
Trigger: A user saved hooks.json in their editor between Orca's snapshot read and the writeHooks callback; another Orca process or codex TUI rewrote hooks.json; the resolved write path (symlink target via resolveHooksJsonWritePath) shifted because the symlink changed.
Common situations: User actively editing hooks.json while Orca does launch-prep hook install; two Orca windows racing; a hook-manager extension rewriting the file; the file is a symlink whose target was swapped.
Related errors
- Orca could not safely move this legacy Codex session into yo
- Legacy rollout source is not a regular file.
- The target filesystem cannot safely install this rollout.
- A different rollout already occupies the real-home target pa
- Failed to invalidate Codex session backfill marker
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/99f1359d5f9e5172.
Report an issue: GitHub.