{"record":{"id":"c7cffde021beb725","repo":"Yeachan-Heo/oh-my-codex","slug":"detached-session-did-not-report-a-leader-pane-id","errorCode":null,"errorMessage":"detached session did not report a leader pane id","messagePattern":"detached session did not report a leader pane id","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/cli/index.ts","lineNumber":6588,"sourceCode":"          hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows, sessionId,\n          projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride, codexEnvWithNotify,\n          sqliteHomeOverride, detachedParentEnvFilePath, inheritedWorkerModel, releaseMarkerPath,\n          omxBin,\n          {\n            ...(preLaunchOptions.notifyTempContract.active ? { notifyTempContract: preLaunchOptions.notifyTempContract } : {}),\n            enableNotifyFallbackAuthority: preLaunchOptions.enableNotifyFallbackAuthority,\n            worktreeDirty: preLaunchOptions.worktreeDirty,\n            shouldAttach: detachedPreflight.shouldAttach,\n          },\n          detachedControlPlane,\n        );\n        for (const step of bootstrapSteps) {\n          try {\n            if (step.name === \"new-session\") {\n              const output = execTmuxFileSync(step.args, { stdio: \"pipe\", encoding: \"utf-8\" });\n              createdSession = true;\n              const leaderPaneId = parsePaneIdFromTmuxOutput(output || \"\");\n              if (!leaderPaneId) throw new Error(\"detached session did not report a leader pane id\");\n              detachedLeaderPaneId = leaderPaneId;\n              detachedLeaderAuthority = captureDetachedLeaderAuthority(leaderPaneId, sessionName, sessionId);\n              continue;\n            }\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\"]);","sourceCodeStart":6570,"sourceCodeEnd":6606,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L6570-L6606","documentation":"During detached bootstrap, the `tmux new-session` step's output could not be parsed into a leader pane id. OMX relies on that pane id as the authority anchor for all subsequent owner-guarded tmux mutations, so an unparseable output is fatal rather than retried.","triggerScenarios":"execTmuxFileSync for the new-session step emits no parseable pane id — because a tmux format/display option in the user's ~/.tmux.conf alters new-session output, an ancient tmux version formats output differently, or tmux printed a warning line instead of the id.","commonSituations":"Custom tmux configs with hooks (hook-attached-session, etc.) that print to stdout; tmux < 3.x with different formatting; tmux banners/messages from plugins like tmux-continuum appearing on session creation.","solutions":["Test with a clean config: `tmux -f /dev/null new-session -d` style check, or launch OMX with TMUX_CONF overrides to rule out config interference","Upgrade tmux to a modern release (3.2+) so new-session output matches the expected format","Audit tmux hooks/plugins in ~/.tmux.conf that write to stdout during session creation and silence them","Report the exact tmux version/output to OMX maintainers if it persists on a clean config"],"exampleFix":"# before (~/.tmux.conf)\nset-hook -g session-created 'run-shell \"echo created\"'\n\n# after\nset-hook -g session-created 'run-shell -b \"echo created >/dev/null\"'","handlingStrategy":"validation","validationCode":"const out = execTmuxFileSync([\"new-session\", \"-d\", \"-P\", \"-F\", \"#{pane_id}\", ...], { stdio: \"pipe\" });\nif (!/^%\\d+$/.test((out || \"\").trim())) { /* abort before authority-dependent steps */ }","typeGuard":"function isPaneId(v: string): boolean { return /^%\\d+$/.test(v.trim()); }","tryCatchPattern":"try { bootstrap(); } catch (e) { if (e.message === \"detached session did not report a leader pane id\") { /* test with tmux -f /dev/null; audit hooks */ } throw e; }","preventionTips":["Keep tmux hooks/plugins from printing to stdout during session creation","Use tmux 3.2 or newer","Test detached launches with a minimal tmux config when debugging"],"tags":["tmux","bootstrap","parse-error","pane-id"],"backgroundTag":"tmux-output-parse-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}