Yeachan-Heo/oh-my-codex · critical · Error
shutdown_config_missing_after_detached_reconciliation
Error message
shutdown_config_missing_after_detached_reconciliation:${sanitized} What it means
Fail-closed guard in team shutdown: after reconciling detached-session destroy receipts, the team config can no longer be read. The shutdown deliberately aborts rather than proceed without authoritative config, naming the team in the message.
Solutions
- Check whether another shutdown already completed and removed the team config; if so, treat shutdown as done
- Restore or recreate the team config, then re-run shutdown
- Serialize shutdowns per team (lock) and stop external deletions of team state during shutdown
Example fix
// before
await shutdownTeam(team, cwd);
// after
const config = await readTeamConfig(team, cwd);
if (!config) { /* already gone */ return; }
await withTeamShutdownLock(team, () => shutdownTeam(team, cwd)); Defensive patterns
Strategy: fallback
Validate before calling
const config = await readTeamConfig(teamName, cwd); if (!config) return; // already shut down
Try / catch
try { await shutdownTeam(t, cwd); } catch (e) { if (/^shutdown_config_missing_after_detached_reconciliation:/.test((e as Error).message)) return; /* idempotent */ throw e; } Prevention
- Make shutdown idempotent; tolerate already-deleted configs
- Serialize shutdown per team
- Prevent external deletions of team state during shutdown
When it happens
Trigger: Shutting down a team whose config disappears or becomes unreadable specifically after reconcileDetachedSessionDestroyReceipt runs — e.g. the reconciliation itself removed/renamed the state, or an external process deleted the config concurrently.
Common situations: Concurrent shutdown invocations racing on the same team; external cleanup scripts deleting team state mid-shutdown; corrupted config file that readTeamConfig cannot parse (returns null).
Related errors
- shutdown_config_missing_after_commit
- shutdown_ _ _identity_changed
- `allowed_modes` must be a non-empty string array
- [api] failed to launch native binary: executable not found
- bound setup finalization denied
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/096ad61e84b32cee.
Report an issue: GitHub.
Appendix: source
Thrown at src/team/runtime.ts:4872
let skipWorkerAcks = false;
const sanitized = resolveTeamNameForCurrentContext(teamName, cwd);
let config = await readTeamConfig(sanitized, cwd);
if (!config) {
await reconcileDetachedSessionDestroyReceipt(sanitized, cwd, null);
await reconcileGonePaneDescendantCleanupDebt(sanitized, cwd);
// A missing config is not authority over a conventionally named tmux
// session. It may be another team's or a recycled user session.
await cleanupTeamState(sanitized, cwd);
await syncTeamModeStateOnShutdown(sanitized, cwd);
restoreTeamModelInstructionsFile(sanitized);
return { commitHygieneArtifacts: null };
}
// Reconcile accepted detached-session destruction before any other shutdown
// effect. A receipt is the only durable authority across the kill/query crash
// window and is deliberately fail-closed on malformed or unavailable input.
await reconcileDetachedSessionDestroyReceipt(sanitized, cwd, config);
config = await readTeamConfig(sanitized, cwd);
if (!config) throw new Error(`shutdown_config_missing_after_detached_reconciliation:${sanitized}`);
config = await reconcileStartupCleanupPanes(config, cwd);
const restoredHudDebtRoot = join(config.team_state_root ?? resolveCanonicalTeamStateRoot(cwd), 'team', sanitized);
const configuredRestoredHudPaneId = typeof config.hud_pane_id === 'string' && /^%[0-9]+$/.test(config.hud_pane_id)
? config.hud_pane_id
: null;
const configuredRestoredHudPanePid = typeof config.hud_pane_pid === 'number'
&& Number.isSafeInteger(config.hud_pane_pid)
&& config.hud_pane_pid > 0
? config.hud_pane_pid
: null;
if (configuredRestoredHudPaneId && configuredRestoredHudPanePid) {
try {
// A restored-HUD debt is finalized only when this canonical config
// transaction records its exact frozen pane identity. A stale config may
// point to a different HUD after a crash, so replay the pinned debt
// rather than treating that mismatch as successful finalization.
finalizeRestoredHudCleanupDebtSync(
cwd,View on GitHub (pinned to 3ad79a8a6f)