Yeachan-Heo/oh-my-codex · critical · Error
detached ready report does not bind the inert session
Error message
detached ready report does not bind the inert session
What it means
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.
Source
Thrown at src/cli/index.ts:6665
shouldAttach: detachedPreflight.shouldAttach,
leaderPaneId: detachedLeaderPaneId,
leaderPanePid: detachedLeaderAuthority?.panePid ?? null,
})) {
detachedLeaderPid = report!.leaderPid!;
return { kind: "success" };
}
if (report?.nonce === detachedLaunchNonce && report.sessionId === sessionId && report.sessionName === sessionName && report.leaderPid && report.kind === "failed") {
detachedLeaderPid = report.leaderPid;
return { kind: "failure", operation: "session-instructions", error: new Error(report.error || "detached leader setup failed") };
}
if (Date.now() >= readyDeadline) return { kind: "failure", operation: "session-instructions", error: new Error("detached leader readiness timed out") };
blockMs(20);
}
},
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) => {View on GitHub (pinned to 3ad79a8a6f)
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
Example fix
# before $ omx launch --detached # after a crashed prior launch # after $ omx cleanup --detached # or: rm -f ~/.omx/state/detached-*.release* $ omx launch --detached
Defensive patterns
Strategy: fallback
Validate before calling
const report = readDetachedLeaderReport(markerPath); const ok = report?.kind === "ready" && report.nonce === nonce && report.sessionId === sid && report.sessionName === name && report.leaderPid === pid; if (!ok) await cleanStaleDetachedState();
Type guard
function bindsLaunch(r: any, l: { nonce: string; sessionId: string; sessionName: string; leaderPid: number }): boolean {
return r?.kind === "ready" && r.nonce === l.nonce && r.sessionId === l.sessionId && r.sessionName === l.sessionName && r.leaderPid === l.leaderPid;
} Try / catch
try { establish(); } catch (e) { if (/does not bind the inert session/.test(e.message)) { await cleanStaleMarkers(); return establish(); } throw e; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- detached active record does not bind the ready leader
- detached launch requires a frozen available preflight
- detached ready report does not bind the leader pane
- detached leader authority missing before rollback
- startup_cleanup_pane_pid_missing:${cleanupPane.pane_id}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/5b138a51797ee1da.
Report an issue: GitHub.