{"record":{"id":"aa3b0c5c69d6a60e","repo":"Yeachan-Heo/oh-my-codex","slug":"unexpected-detached-bootstrap-mutation-step-nam","errorCode":null,"errorMessage":"unexpected detached bootstrap mutation: ${step.name}","messagePattern":"unexpected detached bootstrap mutation: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/cli/index.ts","lineNumber":6610,"sourceCode":"            }\n            const authority = detachedLeaderAuthority;\n            if (!authority) throw new Error(\"detached leader authority missing before tmux mutation\");\n            if (step.name === \"tag-session\") {\n              runDetachedLeaderMutation(authority, step.args, false);\n              // tmux can acknowledge the session tag before the first owner-format\n              // evaluation sees it. Retrying this idempotent first owner-guarded\n              // mutation once gives the server a command boundary without relaxing\n              // any part of the captured session, window, pane, PID, or owner fence.\n              runDetachedLeaderMutation(authority, [\"set-option\", \"-q\", \"-t\", authority.sessionName, \"history-limit\", String(DETACHED_TMUX_HISTORY_LIMIT)], true, true);\n              runDetachedLeaderMutation(authority, [\"set-option\", \"-pq\", \"-t\", authority.paneId, \"history-limit\", String(DETACHED_TMUX_HISTORY_LIMIT)]);\n              // #3266: the owned leader pane must close with its process so a normal\n              // child exit destroys the session naturally even when the user's tmux\n              // config inherits remain-on-exit=on/failed.\n              runDetachedLeaderMutation(authority, [\"set-option\", \"-pq\", \"-t\", authority.paneId, \"remain-on-exit\", \"off\"]);\n              continue;\n            }\n            if (step.name !== \"split-and-capture-hud-pane\") {\n              throw new Error(`unexpected detached bootstrap mutation: ${step.name}`);\n            }\n            detachedHudAuthority = runDetachedLeaderSplit(authority, step.args);\n            tagDetachedHudPane(authority, detachedHudAuthority, sessionId);\n            for (const finalizeStep of buildDetachedSessionFinalizeSteps(\n              authority.sessionName, detachedHudAuthority.paneId, authority.windowIndex, process.env.OMX_MOUSE !== \"0\",\n              nativeWindows, detachedPreflight.shouldAttach, authority.paneId,\n            )) {\n              if (finalizeStep.name === \"attach-session\") { attachStep = finalizeStep; continue; }\n              if (finalizeStep.name === \"sanitize-copy-mode-style\") continue;\n              const targetsHudPane = new Set([\n                \"register-resize-hook\",\n                \"register-client-attached-reconcile\",\n                \"schedule-delayed-resize\",\n                \"reconcile-hud-resize\",\n              ]).has(finalizeStep.name);\n              if (targetsHudPane) runDetachedHudMutation(authority, detachedHudAuthority, guardDetachedHudDeferredMutation(authority, detachedHudAuthority, finalizeStep.args));\n              else runDetachedLeaderMutation(authority, finalizeStep.args);\n            }","sourceCodeStart":6592,"sourceCodeEnd":6628,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L6592-L6628","documentation":"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.","triggerScenarios":"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.","commonSituations":"Stale build outputs after pulling new code without rebuilding; monorepo version skew between packages; forks that add steps without extending the walker.","solutions":["Rebuild/reinstall so all OMX artifacts come from one consistent version (git pull && rebuild, or npm i -g omx@latest)","If you maintain a fork, update the walker switch to handle your added step names or filter them out","Clear node_modules and dist caches to eliminate stale mixed artifacts"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const KNOWN = new Set([\"new-session\", \"tag-session\", \"remain-on-exit\", \"split-and-capture-hud-pane\"]);\nif (steps.some((s) => !KNOWN.has(s.name))) throw new Error(\"unknown bootstrap step\");","typeGuard":null,"tryCatchPattern":"try { run(); } catch (e) { if (/unexpected detached bootstrap mutation/.test(e.message)) { /* reinstall matching version */ } }","preventionTips":["Keep OMX artifacts on a single version (clean rebuild after upgrades)","Extend the walker whenever adding steps in forks","Avoid mixing dist outputs from different checkouts"],"tags":["tmux","bootstrap","invariant","version-skew"],"backgroundTag":"unhandled-step-in-pipeline","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}