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

unexpected detached bootstrap mutation: ${step.name}

Error message

unexpected detached bootstrap mutation: ${step.name}

What it means

The detached bootstrap step walker encountered a step name it has no handler for. It explicitly handles new-session, tag-session, remain-on-exit, and split-and-capture-hud-pane; any other step name in the list throws immediately. This is a programming/version invariant protecting against unknown mutations.

Source

Thrown at src/cli/index.ts:6610

            }
            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);
            tagDetachedHudPane(authority, detachedHudAuthority, sessionId);
            for (const finalizeStep of buildDetachedSessionFinalizeSteps(
              authority.sessionName, detachedHudAuthority.paneId, authority.windowIndex, process.env.OMX_MOUSE !== "0",
              nativeWindows, detachedPreflight.shouldAttach, authority.paneId,
            )) {
              if (finalizeStep.name === "attach-session") { attachStep = finalizeStep; continue; }
              if (finalizeStep.name === "sanitize-copy-mode-style") continue;
              const targetsHudPane = new Set([
                "register-resize-hook",
                "register-client-attached-reconcile",
                "schedule-delayed-resize",
                "reconcile-hud-resize",
              ]).has(finalizeStep.name);
              if (targetsHudPane) runDetachedHudMutation(authority, detachedHudAuthority, guardDetachedHudDeferredMutation(authority, detachedHudAuthority, finalizeStep.args));
              else runDetachedLeaderMutation(authority, finalizeStep.args);
            }

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Rebuild/reinstall so all OMX artifacts come from one consistent version (git pull && rebuild, or npm i -g omx@latest)
  2. If you maintain a fork, update the walker switch to handle your added step names or filter them out
  3. Clear node_modules and dist caches to eliminate stale mixed artifacts
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN = new Set(["new-session", "tag-session", "remain-on-exit", "split-and-capture-hud-pane"]);
if (steps.some((s) => !KNOWN.has(s.name))) throw new Error("unknown bootstrap step");

Try / catch

try { run(); } catch (e) { if (/unexpected detached bootstrap mutation/.test(e.message)) { /* reinstall matching version */ } }

Prevention

When it happens

Trigger: Only occurs if buildDetachedBootstrapSteps emits a step with an unexpected name — e.g. mixing versions of compiled artifacts, hand-editing the steps array, or a partial upgrade where a step builder from a newer version feeds an older walker.

Common situations: Stale build outputs after pulling new code without rebuilding; monorepo version skew between packages; forks that add steps without extending the walker.

Related errors


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