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

detached leader authority missing before tmux mutation

Error message

detached leader authority missing before tmux mutation

What it means

Inside the detached bootstrap step loop, a non-new-session step was reached before a leader authority had been captured. All owner-guarded tmux mutations require the captured authority (pane id, session name, PIDs) from the new-session step; reaching a mutation step without it means the state machine invariant broke.

Source

Thrown at src/cli/index.ts:6594

            enableNotifyFallbackAuthority: preLaunchOptions.enableNotifyFallbackAuthority,
            worktreeDirty: preLaunchOptions.worktreeDirty,
            shouldAttach: detachedPreflight.shouldAttach,
          },
          detachedControlPlane,
        );
        for (const step of bootstrapSteps) {
          try {
            if (step.name === "new-session") {
              const output = execTmuxFileSync(step.args, { stdio: "pipe", encoding: "utf-8" });
              createdSession = true;
              const leaderPaneId = parsePaneIdFromTmuxOutput(output || "");
              if (!leaderPaneId) throw new Error("detached session did not report a leader pane id");
              detachedLeaderPaneId = leaderPaneId;
              detachedLeaderAuthority = captureDetachedLeaderAuthority(leaderPaneId, sessionName, sessionId);
              continue;
            }
            const authority = detachedLeaderAuthority;
            if (!authority) throw new Error("detached leader authority missing before tmux mutation");
            if (step.name === "tag-session") {
              runDetachedLeaderMutation(authority, step.args, false);
              // tmux can acknowledge the session tag before the first owner-format
              // evaluation sees it. Retrying this idempotent first owner-guarded
              // mutation once gives the server a command boundary without relaxing
              // any part of the captured session, window, pane, PID, or owner fence.
              runDetachedLeaderMutation(authority, ["set-option", "-q", "-t", authority.sessionName, "history-limit", String(DETACHED_TMUX_HISTORY_LIMIT)], true, true);
              runDetachedLeaderMutation(authority, ["set-option", "-pq", "-t", authority.paneId, "history-limit", String(DETACHED_TMUX_HISTORY_LIMIT)]);
              // #3266: the owned leader pane must close with its process so a normal
              // child exit destroys the session naturally even when the user's tmux
              // config inherits remain-on-exit=on/failed.
              runDetachedLeaderMutation(authority, ["set-option", "-pq", "-t", authority.paneId, "remain-on-exit", "off"]);
              continue;
            }
            if (step.name !== "split-and-capture-hud-pane") {
              throw new Error(`unexpected detached bootstrap mutation: ${step.name}`);
            }
            detachedHudAuthority = runDetachedLeaderSplit(authority, step.args);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Treat this as a follow-on of error 187: fix why new-session did not yield a leader pane id (clean tmux config, modern tmux)
  2. If you forked/modified the bootstrap steps, ensure new-session runs first and short-circuits on failure
  3. Capture the full bootstrap log and tmux new-session output to see which step was reached without authority
  4. Report upstream — this invariant firing indicates either corrupted step order or swallowed earlier errors
Defensive patterns

Strategy: try-catch

Validate before calling

const steps = buildDetachedBootstrapSteps();
if (steps[0]?.name !== "new-session") throw new Error("step order corrupted");

Try / catch

try { runBootstrap(steps); } catch (e) { if (/leader authority missing/.test(e.message)) { /* inspect earlier step failures first */ } throw e; }

Prevention

When it happens

Trigger: Practically reached when the new-session step failed to produce a leader pane id (see error 187) but the loop continued, or when the step list was constructed/reordered so a mutation step precedes new-session. It is a defensive invariant check for the detached bootstrap state machine.

Common situations: Almost never seen in normal use; appears in modified/forked code that reorders bootstrap steps, or as a downstream symptom when new-session output parsing failed but execution fell through.

Related errors


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