{"record":{"id":"84ef54c6d5cf2972","repo":"Yeachan-Heo/oh-my-codex","slug":"detached-session-name-metadata-was-not-committed-b","errorCode":null,"errorMessage":"detached session-name metadata was not committed by the leader","messagePattern":"detached session-name metadata was not committed by the leader","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/cli/index.ts","lineNumber":6679,"sourceCode":"          },\n          createInertSession: async () => {\n            const report = readDetachedLeaderReport(releaseMarkerPath);\n            if (report?.kind !== \"ready\" || report.nonce !== detachedLaunchNonce || report.sessionId !== sessionId || report.sessionName !== sessionName || report.leaderPid !== detachedLeaderPid) {\n              throw new Error(\"detached ready report does not bind the inert session\");\n            }\n            return sessionName;\n          },\n          capturePane: async () => {\n            const report = readDetachedLeaderReport(releaseMarkerPath);\n            if (!detachedLeaderPaneId || report?.kind !== \"ready\" || report.paneId !== detachedLeaderPaneId || report.leaderPid !== detachedLeaderPid) {\n              throw new Error(\"detached ready report does not bind the leader pane\");\n            }\n            return detachedLeaderPaneId;\n          },\n          updateNameMetadata: async () => {\n            const state = await readSessionState(cwd, detachedSelectedStateEnv);\n            if (state?.session_id !== sessionId || state.tmux_session_name !== sessionName) {\n              throw new Error(\"detached session-name metadata was not committed by the leader\");\n            }\n            return \"committed-released\";\n          },\n          updatePaneMetadata: async (_binding, pane) => {\n            const state = await readSessionState(cwd, detachedSelectedStateEnv);\n            if (state?.session_id !== sessionId || state.tmux_pane_id !== pane) {\n              throw new Error(\"detached pane metadata was not committed by the leader\");\n            }\n            return \"committed-released\";\n          },\n          publishActiveRecord: async () => {\n            const activeRecordPath = contextKey ? madmaxDetachedActiveRecordPath(runsRoot, contextKey) : join(omxRoot(cwd), \"state\", \"detached-active-record.json\");\n            const record = readMadmaxDetachedActiveRecord(activeRecordPath);\n            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\");\n            const bytes = readFileSync(activeRecordPath, \"utf-8\");\n            return { bytes, digest: createHash(\"sha256\").update(bytes).digest(\"hex\"), nonce: detachedLaunchNonce };\n          },\n          finalizeSetupFailure: async () => {},","sourceCodeStart":6661,"sourceCodeEnd":6697,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L6661-L6697","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const state = await readSessionState(cwd, env);\nif (state?.session_id !== sessionId || state.tmux_session_name !== sessionName) await sleep(50); // allow leader write to land","typeGuard":"function stateMatches(s: any, sid: string, name: string): boolean { return s?.session_id === sid && s?.tmux_session_name === name; }","tryCatchPattern":"try { establish(); } catch (e) { if (/session-name metadata was not committed/.test(e.message)) { await cleanStaleState(); return establish(); } throw e; }","preventionTips":["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"],"tags":["detached-launch","session-state","metadata","race-condition"],"backgroundTag":"state-commit-verification-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}