{"record":{"id":"b534e24e9df70c2c","repo":"Yeachan-Heo/oh-my-codex","slug":"prelaunch-completion-operation-failed","errorCode":null,"errorMessage":"preLaunch ${completion.operation} failed","messagePattern":"preLaunch (.+?) failed","errorType":"exception","errorClass":"AggregateError","httpStatus":null,"severity":"error","filePath":"src/cli/index.ts","lineNumber":6263,"sourceCode":"  return degraded.length === 0 ? { kind: \"success\" } : { kind: \"degraded-success\", operations: degraded };\n}\n\nexport async function preLaunch(\n  cwd: string,\n  sessionId: string,\n  notifyTempContract?: NotifyTempContract,\n  codexHomeOverride?: string,\n  enableNotifyFallbackAuthority: boolean = false,\n  worktreeDirty: boolean = false,\n): Promise<PreLaunchResult> {\n  const established = await establishPreLaunchBinding(cwd, sessionId);\n  const completion = {\n    ...await completePreLaunchSetup(cwd, sessionId, notifyTempContract, codexHomeOverride, enableNotifyFallbackAuthority, worktreeDirty),\n    establishmentCleanup: established.cleanup,\n  } satisfies CompletionResult;\n  if (completion.kind === \"failure\") {\n    try { await failPreLaunchSetup(established.binding); }\n    catch (cleanupError) { throw new AggregateError([completion.error, cleanupError], `preLaunch ${completion.operation} failed`); }\n    throw completion.error;\n  }\n  return { binding: established.binding, completion };\n}\n\n/**\n * runCodex: Launch Codex CLI (blocks until exit).\n * All 3 paths (new tmux, existing tmux, no tmux) block via execSync/execFileSync.\n */\nasync function runCodex(\n  cwd: string,\n  args: string[],\n  sessionId: string,\n  workerDefaultModel: string | undefined,\n  codexHomeOverride: string | undefined,\n  sqliteHomeOverride: string | undefined,\n  notifyTempContractRaw: string | null,\n  preLaunchOptions: {","sourceCodeStart":6245,"sourceCodeEnd":6281,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L6245-L6281","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the AggregateError: [0] is the original failure cause — fix that first; [1] explains why rollback could not complete","Manually clean leftover launch state (kill the detached tmux session, remove state files under omx root state/) before relaunching","Check tmux/notify-related preconditions (tmux installed, temp dirs writable) that the named operation depends on","Update OMX — rollback robustness for half-created state is the kind of thing patched between versions"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isPreLaunchAggregate(e: unknown): e is AggregateError {\n  return e instanceof AggregateError && /^preLaunch .+ failed$/.test(e.message);\n}","tryCatchPattern":"try { await establishDetached(); } catch (e) { if (isPreLaunchAggregate(e)) { const [cause, cleanupErr] = e.errors; handle(cause); log(cleanupErr); await manualCleanup(); } }","preventionTips":["Treat errors[0] as the root cause; cleanupErr only explains leftover state","Manually clean half-created sessions when rollback itself failed","Serialize launches to keep pre-launch state consistent"],"tags":["aggregate-error","prelaunch","rollback","state-machine"],"backgroundTag":"setup-rollback-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}