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

No Autopilot state found. Run `omx autopilot start --task <t

Error message

No Autopilot state found. Run `omx autopilot start --task <text>` first.

What it means

Thrown when an autopilot subcommand other than start needs persisted autopilot state but readAutopilot() returns nothing for the current cwd/session. Autopilot state is created only by `autopilot start`, so any follow-up command before that fails here.

Source

Thrown at src/cli/autopilot.ts:132

    const state = await startMode('autopilot', task, 3, cwd, sessionId);
    const initialized = await updateAutopilotPipelineState({
      ...state,
      active: true,
      current_phase: 'deep-interview',
      session_id: sessionId,
      workingDirectory: cwd,
      phase_cycle: ['deep-interview', 'ralplan', 'ultragoal'],
      handoff_artifacts: {},
      deep_interview_gate: { status: 'required' },
      review_cycle: 0,
    }, cwd, sessionId);
    if (json) stdout(JSON.stringify({ ok: true, state: initialized, instruction: instruction(initialized) }));
    else stdout(instruction(initialized));
    return;
  }

  const state = await readAutopilot(cwd, sessionId);
  if (!state) throw new Error('No Autopilot state found. Run `omx autopilot start --task <text>` first.');

  if (command === 'status' || command === 'next') {
    const nextInstruction = instruction(state);
    const skippedGates = skippedGateReport(state as unknown as Record<string, unknown>);
    if (json) stdout(JSON.stringify({ state, instruction: nextInstruction }));
    else if (command === 'next') stdout(nextInstruction);
    else stdout([skippedGates ?? `autopilot: ${state.current_phase}`, nextInstruction].join('\n'));
    return;
  }

  if (command === 'advance') {
    const to = value(rest, '--to');
    if (to !== 'ralplan' && to !== 'ultragoal') throw new Error('--to must be ralplan or ultragoal.');
    const rawHandoff = value(rest, '--handoff-json');
    if (!rawHandoff) throw new Error('Missing --handoff-json.');
    const handoff = await jsonInput(rawHandoff);
    assertBoundHandoffIdentity(handoff, cwd, sessionId);
    const updated = await updateAutopilotPipelineState({

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Run `omx autopilot start --task <text>` first to create the state
  2. If you expected existing state, verify you are in the same working directory and session as when start was run
  3. Check that state files were not removed by cleanup/git clean and re-run start if needed

Example fix

// before
omx autopilot next
// after
omx autopilot start --task "..." && omx autopilot next
Defensive patterns

Strategy: validation

Validate before calling

const state = await readAutopilotState(cwd, sessionId);
if (!state) { await autopilotCommand(['start','--task',task]); }

Try / catch

try { await autopilotCommand(['next']); } catch (e) { if (e.message.includes('No Autopilot state found')) { await autopilotCommand(['start','--task',task]); await autopilotCommand(['next']); } else throw e; }

Prevention

When it happens

Trigger: Running `omx autopilot status`, `next`, or `advance` before ever running `autopilot start --task ...` in this workspace/session, or after state files were deleted or written under a different session id.

Common situations: Fresh clone or cleaned state directory, running follow-up commands in a new session (state lookup is keyed by cwd/session), or a prior start that crashed before persisting state.

Related errors


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