{"record":{"id":"5b138a51797ee1da","repo":"Yeachan-Heo/oh-my-codex","slug":"detached-ready-report-does-not-bind-the-inert-sess","errorCode":null,"errorMessage":"detached ready report does not bind the inert session","messagePattern":"detached ready report does not bind the inert session","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/cli/index.ts","lineNumber":6665,"sourceCode":"                shouldAttach: detachedPreflight.shouldAttach,\n                leaderPaneId: detachedLeaderPaneId,\n                leaderPanePid: detachedLeaderAuthority?.panePid ?? null,\n              })) {\n                detachedLeaderPid = report!.leaderPid!;\n                return { kind: \"success\" };\n              }\n              if (report?.nonce === detachedLaunchNonce && report.sessionId === sessionId && report.sessionName === sessionName && report.leaderPid && report.kind === \"failed\") {\n                detachedLeaderPid = report.leaderPid;\n                return { kind: \"failure\", operation: \"session-instructions\", error: new Error(report.error || \"detached leader setup failed\") };\n              }\n              if (Date.now() >= readyDeadline) return { kind: \"failure\", operation: \"session-instructions\", error: new Error(\"detached leader readiness timed out\") };\n              blockMs(20);\n            }\n          },\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) => {","sourceCodeStart":6647,"sourceCodeEnd":6683,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L6647-L6683","documentation":"During detached establishment, the 'ready' report read from the release marker must match the launch nonce, sessionId, sessionName, and leaderPid exactly. If the report is missing, of the wrong kind, or any identity field mismatches, establishment aborts — this binding check prevents attaching OMX to a tmux session created by a different (possibly stale) launch.","triggerScenarios":"readDetachedLeaderReport on the release marker path returns a report whose kind is not 'ready', or whose nonce/sessionId/sessionName/leaderPid differ from the current launch — e.g. a stale marker from a previous launch, a leader that died and a new one wrote a marker, or marker file corruption.","commonSituations":"Relaunching after an unclean exit where the old release marker file was left behind; concurrent launches sharing a marker path; crashes between marker write and cleanup leaving mismatched state.","solutions":["Remove stale detached launch marker/state files under the OMX state directory before relaunching","Ensure only one detached launch per session/marker path runs at a time","Retry the launch after killing orphaned tmux sessions and leader processes from the prior attempt","If persistent, capture the marker file contents and the expected values to diagnose which field mismatches"],"exampleFix":"# before\n$ omx launch --detached # after a crashed prior launch\n\n# after\n$ omx cleanup --detached   # or: rm -f ~/.omx/state/detached-*.release*\n$ omx launch --detached","handlingStrategy":"fallback","validationCode":"const report = readDetachedLeaderReport(markerPath);\nconst ok = report?.kind === \"ready\" && report.nonce === nonce && report.sessionId === sid && report.sessionName === name && report.leaderPid === pid;\nif (!ok) await cleanStaleDetachedState();","typeGuard":"function bindsLaunch(r: any, l: { nonce: string; sessionId: string; sessionName: string; leaderPid: number }): boolean {\n  return r?.kind === \"ready\" && r.nonce === l.nonce && r.sessionId === l.sessionId && r.sessionName === l.sessionName && r.leaderPid === l.leaderPid;\n}","tryCatchPattern":"try { establish(); } catch (e) { if (/does not bind the inert session/.test(e.message)) { await cleanStaleMarkers(); return establish(); } throw e; }","preventionTips":["Clean detached release markers after crashes before relaunching","One detached launch per marker path at a time","Treat binding mismatches as stale state, not transient errors — clean then retry once"],"tags":["detached-launch","identity-binding","stale-state","tmux"],"backgroundTag":"stale-state-mismatch","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}