Yeachan-Heo/oh-my-codex · critical · Error
detached session-name metadata was not committed by the lead
Error message
detached session-name metadata was not committed by the leader
What it means
After instructing the leader to commit session-name metadata, OMX re-reads session state and requires session_id and tmux_session_name to match the current launch. A mismatch means the leader never committed (or committed different) session-name metadata, so the establishment handshake fails.
Source
Thrown at src/cli/index.ts:6679
},
createInertSession: async () => {
const report = readDetachedLeaderReport(releaseMarkerPath);
if (report?.kind !== "ready" || report.nonce !== detachedLaunchNonce || report.sessionId !== sessionId || report.sessionName !== sessionName || report.leaderPid !== detachedLeaderPid) {
throw new Error("detached ready report does not bind the inert session");
}
return sessionName;
},
capturePane: async () => {
const report = readDetachedLeaderReport(releaseMarkerPath);
if (!detachedLeaderPaneId || report?.kind !== "ready" || report.paneId !== detachedLeaderPaneId || report.leaderPid !== detachedLeaderPid) {
throw new Error("detached ready report does not bind the leader pane");
}
return detachedLeaderPaneId;
},
updateNameMetadata: async () => {
const state = await readSessionState(cwd, detachedSelectedStateEnv);
if (state?.session_id !== sessionId || state.tmux_session_name !== sessionName) {
throw new Error("detached session-name metadata was not committed by the leader");
}
return "committed-released";
},
updatePaneMetadata: async (_binding, pane) => {
const state = await readSessionState(cwd, detachedSelectedStateEnv);
if (state?.session_id !== sessionId || state.tmux_pane_id !== pane) {
throw new Error("detached pane metadata was not committed by the leader");
}
return "committed-released";
},
publishActiveRecord: async () => {
const activeRecordPath = contextKey ? madmaxDetachedActiveRecordPath(runsRoot, contextKey) : join(omxRoot(cwd), "state", "detached-active-record.json");
const record = readMadmaxDetachedActiveRecord(activeRecordPath);
if (!record || record.launch_nonce !== detachedLaunchNonce || record.leader_pid !== detachedLeaderPid || record.session_id !== sessionId || record.tmux_session_name !== sessionName || record.tmux_pane_id !== detachedLeaderPaneId) throw new Error("detached active record does not bind the ready leader");
const bytes = readFileSync(activeRecordPath, "utf-8");
return { bytes, digest: createHash("sha256").update(bytes).digest("hex"), nonce: detachedLaunchNonce };
},
finalizeSetupFailure: async () => {},View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Delete stale session state files under the OMX root state directory and retry the launch
- Ensure the launch env (CODEX_HOME, OMX root vars) is consistent between the leader spawn and the validation step
- Rule out concurrent OMX sessions writing the same state file; serialize launches
- Check the leader process is alive and healthy during bootstrap (tmux session not dying instantly due to a failing command)
Defensive patterns
Strategy: retry
Validate before calling
const state = await readSessionState(cwd, env); if (state?.session_id !== sessionId || state.tmux_session_name !== sessionName) await sleep(50); // allow leader write to land
Type guard
function stateMatches(s: any, sid: string, name: string): boolean { return s?.session_id === sid && s?.tmux_session_name === name; } Try / catch
try { establish(); } catch (e) { if (/session-name metadata was not committed/.test(e.message)) { await cleanStaleState(); return establish(); } throw e; } Prevention
- Keep launch env (CODEX_HOME, OMX root) identical between leader spawn and validation
- Remove stale session state files before relaunching
- Serialize launches writing the same session state file
When it happens
Trigger: readSessionState returns state whose session_id differs or whose tmux_session_name does not match — the leader process died before writing, wrote to a different state file (env-dependent selection via detachedSelectedStateEnv), or a stale state file from a previous session shadows the new one.
Common situations: Leftover state files from crashed sessions; env differences (CODEX_HOME/OMX root overrides) pointing the leader and validator at different state paths; slow disks where the leader write lands after validation; concurrent sessions overwriting shared state.
Related errors
- detached pane metadata was not committed by the leader
- detached ready report does not bind the leader pane
- invalid auth slot path
- ${label} is not a file: ${path}
- Refusing to overwrite existing ${repoRelative(cwd, missionPa
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/84ef54c6d5cf2972.
Report an issue: GitHub.