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

detached leader authority missing before rollback

Error message

detached leader authority missing before rollback

What it means

During rollback of a partially created detached session, the step executor requires detachedLeaderAuthority (the captured pane/session/PID fence) before running each rollback mutation. If creation never got far enough to capture authority but createdSession is true, rollback throws this per-step error (collected by attempt()).

Source

Thrown at src/cli/index.ts:6751

                  kind: report.kind,
                };
              blockMs(20);
            }
            return { acknowledged: false };
          },
          attachOrReturn: async () => { if (attachStep) execTmuxFileSync(attachStep.args, { stdio: "inherit" }); },
          rollback: async (_ownedRecord, report) => {
            const attempt = async (step: DetachedRollbackStep, operation: () => Promise<void> | void): Promise<void> => {
              report.rollback.attempted.push(step);
              try { await operation(); } catch (error) { report.rollback.failures.push({ step, status: "failed", code: detachedFailureCode(error) }); }
            };
            await attempt("parent-env", async () => { if (detachedParentEnvFilePath) await rm(detachedParentEnvFilePath, { force: true }); });
            await attempt("runtime-codex-home", () => cleanupRuntimeCodexHome(runtimeCodexHomeForCleanup, projectLocalCodexHomeForCleanup));
            await attempt("rollback", () => { rmSync(releaseMarkerPath, { force: true }); rmSync(`${releaseMarkerPath}.release`, { force: true }); rmSync(`${releaseMarkerPath}.abort`, { force: true }); });
            if (createdSession) {
              for (const step of buildDetachedSessionRollbackSteps(sessionName, null, null, null)) {
                await attempt(`session:${step.name}`, () => {
                  if (!detachedLeaderAuthority) throw new Error("detached leader authority missing before rollback");
                  if (rollbackFromPreReportAuthority && step.name === "kill-session") {
                    cleanupDetachedPreReportSession(detachedLeaderAuthority);
                    return;
                  }
                  runDetachedLeaderMutation(detachedLeaderAuthority, step.args);
                });
              }
            }
          },
        },
      );
      if (launchTerminal.kind === "attached" && detachedLeaderPid) {
        // #3266: propagate the finalized detached child's exit status to the invoking shell.
        // A rejected status protocol is only benign when the exact owned session
        // provably survives (manual detach); a destroyed or ambiguous session with
        // no authenticated finalized status is a protocol failure, never silent success.
        const attachResolution = resolveDetachedAttachExitStatus(
          releaseMarkerPath,

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Resolve the root bootstrap failure first (clean ~/.tmux.conf interference, upgrade tmux — see error 187)
  2. After a failed launch, manually kill the leftover session: `tmux kill-session -t <name from logs>` since rollback could not
  3. Clean all detached state files before the next attempt
  4. Reinstall/rebuild OMX if you modified bootstrap code

Example fix

# manual cleanup after this error
$ tmux kill-session -t <detached-session-name>
$ rm -f ~/.omx/state/detached-*
Defensive patterns

Strategy: fallback

Validate before calling

if (createdSession && !detachedLeaderAuthority) { await execTmux(`kill-session -t ${sessionName}`); /* manual teardown instead of rollback */ }

Try / catch

try { launch(); } catch (e) { if (e instanceof AggregateError && e.errors.some((x) => /leader authority missing before rollback/.test(String(x)))) { await manualKillSession(); } throw e; }

Prevention

When it happens

Trigger: tmux new-session succeeded (createdSession=true) but leader authority capture failed or was skipped — e.g. pane id parse failure followed by rollback; or session creation happening via a path that does not populate the authority variable.

Common situations: Stacked on errors 187/188: unparseable new-session output leads to no authority, then teardown also fails; custom tmux configs corrupting new-session output are the usual root cause.

Related errors


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