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

autoresearch_active_mode_exists

autoresearch_active_mode_exists

Error message

autoresearch_active_mode_exists:${String(existingModeState.run_id || 'unknown')}

What it means

During run preparation, the runtime checks the mode-state registry and throws (code autoresearch_active_mode_exists) if the 'autoresearch' mode already reports active. This is a second lock layer beyond the active-run state, preventing overlapping mode sessions in shared .omx state.

Source

Thrown at src/autoresearch/runtime.ts:913

  await writeInstructionsFile(contract, manifest);
  await writeRunManifest(manifest);
  await writeJsonFile(ledgerFile, {
    schema_version: 1,
    run_id: runId,
    created_at: nowIso(),
    updated_at: nowIso(),
    entries: [],
  });
  await writeJsonFile(latestEvaluatorFile, {
    run_id: runId,
    status: 'not-yet-run',
    updated_at: nowIso(),
  });

  const existingModeState = await readModeState('autoresearch', projectRoot);
  if (existingModeState?.active) {
    throw new Error(`autoresearch_active_mode_exists:${String(existingModeState.run_id || 'unknown')}`);
  }
  await startMode('autoresearch', taskDescription, 1, projectRoot);
  await activateAutoresearchRun(manifest);
  await updateModeState('autoresearch', {
    current_phase: 'evaluating-baseline',
    run_id: runId,
    run_tag: runTag,
    mission_dir: contract.missionDir,
    mission_file: contract.missionFile,
    sandbox_file: contract.sandboxFile,
    mission_slug: contract.missionSlug,
    repo_root: projectRoot,
    worktree_path: worktreePath,
    baseline_commit: baselineCommit,
    last_kept_commit: manifest.last_kept_commit,
    results_file: resultsFile,
    manifest_path: manifestFile,
    iteration_ledger_path: ledgerFile,

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Check for a genuinely running autoresearch process; if none, end the mode via the supported cancel/finalize path for the reported run_id
  2. Clear the stale mode state for 'autoresearch' (or both lock states together) using the CLI's recovery command — never just one
  3. If the run_id is 'unknown', both state files are inconsistent; reset autoresearch state via the documented recovery flow
  4. Serialize autoresearch invocations per repo root to avoid racing the two locks
Defensive patterns

Strategy: try-catch

Validate before calling

// mirror the mode-state check before preparing a run
const modeState = await readModeState('autoresearch', repoRoot);
if (modeState?.active) throw new Error(`autoresearch mode already active (${modeState.run_id ?? 'unknown'})`);

Type guard

function isActiveModeState(v: unknown): v is { active: true; run_id?: string } {
  return typeof v === 'object' && v !== null && (v as any).active === true;
}

Try / catch

try { await prepareAutoresearchRuntime(repoRoot, task); }
catch (e) { if (e instanceof Error && e.message.startsWith('autoresearch_active_mode_exists')) { /* end the active mode via recovery, then retry */ } throw e; }

Prevention

When it happens

Trigger: Calling prepareAutoresearchRuntime when readModeState('autoresearch', projectRoot) returns active — e.g. after a prior run crashed without ending its mode, or when the active-run state was cleared but the mode state was not.

Common situations: Crashed or SIGKILLed runs leaving stale mode state, manually clearing only one of the two lock files, or nested/parallel invocations of the CLI in the same repo.

Related errors


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