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

detached launch aborted before release

Error message

detached launch aborted before release

What it means

The launcher wrote an abort report file (matching nonce, sessionId, sessionName, leaderPid) which the leader reads while polling, signalling an intentional abort of the detached launch.

Source

Thrown at src/cli/index.ts:7103

      writeDetachedLeaderReport(payload.readyPath, { version: 1, kind: "ready", nonce, sessionId: payload.sessionId, sessionName: payload.sessionName, paneId: pane, leaderPid: process.pid });
      const releasePath = `${payload.readyPath}.release`;
      const abortPath = `${payload.readyPath}.abort`;
      const releaseDeadline = Date.now() + 30_000;
      let interrupted: NodeJS.Signals | undefined;
      const interrupt = (signal: NodeJS.Signals): void => { interrupted = signal; };
      process.once("SIGINT", () => interrupt("SIGINT"));
      process.once("SIGTERM", () => interrupt("SIGTERM"));
      process.once("SIGHUP", () => interrupt("SIGHUP"));
      while (true) {
        if (interrupted) throw new Error(`detached leader interrupted before release: ${interrupted}`);
        const release = readDetachedLeaderReport(releasePath);
        if (release?.kind === "release" && release.nonce === nonce && release.sessionId === payload.sessionId && release.sessionName === payload.sessionName && release.leaderPid === process.pid) {
          detachedHudProof = parseDetachedHudAuthorityProof(release.hud);
          break;
        }
        const abort = readDetachedLeaderReport(abortPath);
        if (abort?.kind === "abort" && abort.nonce === nonce && abort.sessionId === payload.sessionId && abort.sessionName === payload.sessionName && abort.leaderPid === process.pid) {
          throw new Error("detached launch aborted before release");
        }
        if (Date.now() >= releaseDeadline) throw new Error("detached leader release timed out");
        blockMs(20);
      }
      rmSync(releasePath, { force: true });
      rmSync(abortPath, { force: true });
    }
    const child = spawn(process.platform === "win32" ? "powershell.exe" : "/bin/sh", process.platform === "win32" ? ["-NoProfile", "-Command", payload.codexCmd] : ["-c", payload.codexCmd], {
      cwd: payload.cwd,
      stdio: "inherit",
      ...(process.platform === "win32" ? {} : { detached: true }),
    });
    let escalation: NodeJS.Timeout | undefined;
    const signalChildTree = (signal: NodeJS.Signals, force = false): void => {
      if (!child.pid) return;
      try {
        if (process.platform === "win32") execFileSync("taskkill", ["/PID", String(child.pid), "/T", ...(force ? ["/F"] : [])], { stdio: "ignore" });
        else process.kill(-child.pid, signal);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Check the parent CLI's logs for why it wrote the abort report and address that root cause
  2. Ensure the target tmux session name is unique / not already in use
  3. Retry the launch once transient conditions (locked state, dead panes) are cleared
Defensive patterns

Strategy: try-catch

Try / catch

try { await waitForRelease(); } catch (e) {
  if ((e as Error).message === 'detached launch aborted before release') { /* inspect parent CLI logs for abort cause; fix and retry */ }
}

Prevention

When it happens

Trigger: The parent CLI or a supervisor decides the launch failed (e.g. pane creation issue, validation failure) and writes the abort report before the release report arrives.

Common situations: tmux session name collision, quota/exec failures during pane bootstrap, or the user running a cancel/abort command while launch is pending.

Related errors


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