{"record":{"id":"0e1ed166d42e3093","repo":"Yeachan-Heo/oh-my-codex","slug":"detached-ready-report-does-not-bind-the-leader-pan","errorCode":null,"errorMessage":"detached ready report does not bind the leader pane","messagePattern":"detached ready report does not bind the leader pane","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/cli/index.ts","lineNumber":6672,"sourceCode":"              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) => {\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 () => {","sourceCodeStart":6654,"sourceCodeEnd":6690,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L6654-L6690","documentation":"The capturePane establishment phase re-reads the leader report and requires kind 'ready' with a paneId equal to the captured detachedLeaderPaneId and matching leaderPid. A mismatch means the ready report no longer describes the pane OMX intends to capture, so establishment aborts instead of capturing the wrong pane.","triggerScenarios":"The leader rewrote or rotated the release marker between the createInertSession and capturePane checks — e.g. leader restarted, multiple leaders racing, a stale marker from another launch, or tmux renumbering panes so pane ids diverge.","commonSituations":"Unclean shutdown leftovers making marker/session state inconsistent; rapid successive detached launches; leader process crash-and-retry loops republishing markers.","solutions":["Clean stale detached state (release marker files, detached-active-record.json) and orphaned tmux sessions, then relaunch","Avoid concurrent detached launches against the same cwd/session identity","If it recurs, inspect the marker file's paneId/leaderPid versus the launched session (`tmux list-panes -a`) to find the writer"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const report = readDetachedLeaderReport(markerPath);\nif (!(report?.kind === \"ready\" && report.paneId === detachedLeaderPaneId && report.leaderPid === pid)) await sleep(100); // leader may still be settling","typeGuard":"function bindsPane(r: any, paneId: string, pid: number): boolean { return r?.kind === \"ready\" && r.paneId === paneId && r.leaderPid === pid; }","tryCatchPattern":"try { establish(); } catch (e) { if (/does not bind the leader pane/.test(e.message)) { await cleanStaleDetachedState(); return establish(); } throw e; }","preventionTips":["Avoid concurrent detached launches sharing marker paths","Clean markers/state after unclean exits","Check for orphaned leader processes republishing markers"],"tags":["detached-launch","identity-binding","pane-id","race-condition"],"backgroundTag":"stale-state-mismatch","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}