Yeachan-Heo/oh-my-codex · critical · Error
detached session did not report a leader pane id
Error message
detached session did not report a leader pane id
What it means
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.
Source
Thrown at src/cli/index.ts:6588
hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows, sessionId,
projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride, codexEnvWithNotify,
sqliteHomeOverride, detachedParentEnvFilePath, inheritedWorkerModel, releaseMarkerPath,
omxBin,
{
...(preLaunchOptions.notifyTempContract.active ? { notifyTempContract: preLaunchOptions.notifyTempContract } : {}),
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"]);View on GitHub (pinned to 3ad79a8a6f)
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
Example fix
# before (~/.tmux.conf) set-hook -g session-created 'run-shell "echo created"' # after set-hook -g session-created 'run-shell -b "echo created >/dev/null"'
Defensive patterns
Strategy: validation
Validate before calling
const out = execTmuxFileSync(["new-session", "-d", "-P", "-F", "#{pane_id}", ...], { stdio: "pipe" });
if (!/^%\d+$/.test((out || "").trim())) { /* abort before authority-dependent steps */ } Type guard
function isPaneId(v: string): boolean { return /^%\d+$/.test(v.trim()); } Try / catch
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; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid detached leader authority target
- detached leader authority missing before tmux mutation
- unexpected detached bootstrap mutation: ${step.name}
- invalid auth slot path
- auth directory must not be a symlink: ${dir}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/c7cffde021beb725.
Report an issue: GitHub.