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

preLaunch ${completion.operation} failed

Error message

preLaunch ${completion.operation} failed

What it means

The pre-launch setup state machine completed with kind 'failure', and while rolling back via failPreLaunchSetup the rollback itself also threw. Both the original completion error and the cleanup error are wrapped in an AggregateError labelled 'preLaunch <operation> failed'. The operation name identifies which pre-launch phase (establishment, notify setup, etc.) failed.

Source

Thrown at src/cli/index.ts:6263

  return degraded.length === 0 ? { kind: "success" } : { kind: "degraded-success", operations: degraded };
}

export async function preLaunch(
  cwd: string,
  sessionId: string,
  notifyTempContract?: NotifyTempContract,
  codexHomeOverride?: string,
  enableNotifyFallbackAuthority: boolean = false,
  worktreeDirty: boolean = false,
): Promise<PreLaunchResult> {
  const established = await establishPreLaunchBinding(cwd, sessionId);
  const completion = {
    ...await completePreLaunchSetup(cwd, sessionId, notifyTempContract, codexHomeOverride, enableNotifyFallbackAuthority, worktreeDirty),
    establishmentCleanup: established.cleanup,
  } satisfies CompletionResult;
  if (completion.kind === "failure") {
    try { await failPreLaunchSetup(established.binding); }
    catch (cleanupError) { throw new AggregateError([completion.error, cleanupError], `preLaunch ${completion.operation} failed`); }
    throw completion.error;
  }
  return { binding: established.binding, completion };
}

/**
 * runCodex: Launch Codex CLI (blocks until exit).
 * All 3 paths (new tmux, existing tmux, no tmux) block via execSync/execFileSync.
 */
async function runCodex(
  cwd: string,
  args: string[],
  sessionId: string,
  workerDefaultModel: string | undefined,
  codexHomeOverride: string | undefined,
  sqliteHomeOverride: string | undefined,
  notifyTempContractRaw: string | null,
  preLaunchOptions: {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Read the AggregateError: [0] is the original failure cause — fix that first; [1] explains why rollback could not complete
  2. Manually clean leftover launch state (kill the detached tmux session, remove state files under omx root state/) before relaunching
  3. Check tmux/notify-related preconditions (tmux installed, temp dirs writable) that the named operation depends on
  4. Update OMX — rollback robustness for half-created state is the kind of thing patched between versions
Defensive patterns

Strategy: try-catch

Type guard

function isPreLaunchAggregate(e: unknown): e is AggregateError {
  return e instanceof AggregateError && /^preLaunch .+ failed$/.test(e.message);
}

Try / catch

try { await establishDetached(); } catch (e) { if (isPreLaunchAggregate(e)) { const [cause, cleanupErr] = e.errors; handle(cause); log(cleanupErr); await manualCleanup(); } }

Prevention

When it happens

Trigger: completePreLaunchSetup returns { kind: 'failure' } for some operation (e.g. notify contract setup, codex home preparation); subsequently failPreLaunchSetup throws during rollback — e.g. the resources it tries to undo were already gone or in a broken state.

Common situations: Partial launches after a crash leave half-created artifacts so rollback commands fail; permission changes between setup and teardown; concurrent OMX processes racing to clean the same state.

Related errors


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