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

detached leader PID missing before release

Error message

detached leader PID missing before release

What it means

The releaseBarrier phase must publish a release marker naming the leader PID; if detachedLeaderPid was never captured (undefined/null) the barrier refuses to run. Publishing a release marker without a real leader PID would unblock the leader with an unverifiable identity, so it is a hard invariant.

Source

Thrown at src/cli/index.ts:6699

            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 () => {
            const activeRecordPath = contextKey ? madmaxDetachedActiveRecordPath(runsRoot, contextKey) : join(omxRoot(cwd), "state", "detached-active-record.json");
            const record = readMadmaxDetachedActiveRecord(activeRecordPath);
            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");
            const bytes = readFileSync(activeRecordPath, "utf-8");
            return { bytes, digest: createHash("sha256").update(bytes).digest("hex"), nonce: detachedLaunchNonce };
          },
          finalizeSetupFailure: async () => {},
          releaseBarrier: async () => {
            if (!detachedLeaderPid) throw new Error("detached leader PID missing before release");
            publishDetachedReleaseMarker(releaseMarkerPath, detachedLaunchNonce, sessionId, sessionName, detachedLeaderPid, detachedHudAuthority ?? undefined);
          },
          abortAndAwaitFinalization: async () => {
            // The leader has the retained binding. Publishing abort is the only
            // outer action permitted after a D9 write failure; a mismatched or
            // missing report leaves every artifact and the tmux session intact.
            if (!detachedLeaderPid) {
              rollbackFromPreReportAuthority = detachedLeaderAuthority !== null;
              return { acknowledged: false, rollbackAuthorized: rollbackFromPreReportAuthority };
            }
            const current = readDetachedLeaderReport(releaseMarkerPath);
            if (current?.nonce === detachedLaunchNonce && current.sessionId === sessionId &&
              current.sessionName === sessionName && current.leaderPid === detachedLeaderPid &&
              current.finalized === true && (current.kind === "failed" || current.kind === "terminal")) return {
                acknowledged: true,
                nonce: current.nonce,
                sessionId: current.sessionId,
                sessionName: current.sessionName,

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Fix the upstream bootstrap failure (see errors 187, 190, 192): clean tmux config, clean stale state, modern tmux
  2. Full reset: kill orphaned detached tmux sessions, delete release markers and detached state, then relaunch
  3. If forking, ensure detachedLeaderPid is captured before the establishment callbacks run
Defensive patterns

Strategy: try-catch

Validate before calling

if (!detachedLeaderPid) throw new Error("cannot release: leader PID never captured; cleaning up manually");

Type guard

function hasLeaderPid(v: unknown): v is number { return typeof v === "number" && v > 0; }

Try / catch

try { establish(); } catch (e) { if (/leader PID missing before release/.test(e.message)) { await manualCleanup(); /* session unusable */ } }

Prevention

When it happens

Trigger: Reaching releaseBarrier before any step recorded detachedLeaderPid — normally a downstream consequence of earlier bootstrap failures (new-session produced no pane id, or the leader report binding steps failed) rather than an independent user error.

Common situations: Seen stacked on top of errors 187/190/192 when the bootstrap already degraded; forked code paths skipping the leader-PID capture; extreme edge cases where the leader exits before PID capture.

Related errors


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