Yeachan-Heo/oh-my-codex · critical · Error

detached ready report does not bind the leader pane

Error message

detached ready report does not bind the leader pane

What it means

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.

Source

Thrown at src/cli/index.ts:6672

              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) => {
            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 () => {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Clean stale detached state (release marker files, detached-active-record.json) and orphaned tmux sessions, then relaunch
  2. Avoid concurrent detached launches against the same cwd/session identity
  3. If it recurs, inspect the marker file's paneId/leaderPid versus the launched session (`tmux list-panes -a`) to find the writer
Defensive patterns

Strategy: retry

Validate before calling

const report = readDetachedLeaderReport(markerPath);
if (!(report?.kind === "ready" && report.paneId === detachedLeaderPaneId && report.leaderPid === pid)) await sleep(100); // leader may still be settling

Type guard

function bindsPane(r: any, paneId: string, pid: number): boolean { return r?.kind === "ready" && r.paneId === paneId && r.leaderPid === pid; }

Try / catch

try { establish(); } catch (e) { if (/does not bind the leader pane/.test(e.message)) { await cleanStaleDetachedState(); return establish(); } throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: Unclean shutdown leftovers making marker/session state inconsistent; rapid successive detached launches; leader process crash-and-retry loops republishing markers.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/0e1ed166d42e3093. Report an issue: GitHub.