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

No runnable mission tasks found in ${parsed.file}.

Error message

No runnable mission tasks found in ${parsed.file}.

What it means

During mission run, the input file was read and parsed by parseMissionTasks but produced zero tasks. The mission file contains no runnable task entries.

Source

Thrown at src/cli/mission.ts:439

      await runSelectedTasks(summary, paths, parsed, now, stdout, runTask, shouldRun);
      summary.status = missionStatus(summary.tasks);
      summary.completed_at = now().toISOString();
      summary.counts = missionCounts(summary.tasks);
      await persistSummary(paths.summaryPath, summary);
      await appendLedger(paths.ledgerPath, { event: "mission_completed", at: summary.completed_at, slug: summary.slug, status: summary.status, counts: summary.counts });
      if (parsed.json) stdout(JSON.stringify({ ok: summary.status === "passed", summary_path: paths.summaryPath, ledger_path: paths.ledgerPath, summary }, null, 2));
      else {
        stdout(`mission ${parsed.action} ${summary.status}: ${summary.slug}`);
        stdout(`summary: ${paths.summaryPath}`);
        stdout(`ledger: ${paths.ledgerPath}`);
      }
      if (summary.status !== "passed") process.exitCode = 1;
      return;
    }

    const input = await readFile(paths.inputPath, "utf-8");
    const tasks = parseMissionTasks(input);
    if (tasks.length === 0) throw new MissionCommandError(`No runnable mission tasks found in ${parsed.file}.`);

    const startedAt = now().toISOString();
    const summary: MissionSummary = {
      version: 1,
      slug: paths.slug,
      input_path: paths.inputPath,
      dry_run: parsed.dryRun,
      continue_on_error: parsed.continueOnError,
      started_at: startedAt,
      status: parsed.dryRun ? "planned" : "running",
      counts: missionCounts(tasks),
      codex_args: parsed.codexArgs,
      tasks,
    };

    if (parsed.dryRun) {
      for (const task of summary.tasks) task.status = "planned";
      summary.counts = missionCounts(summary.tasks);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Check the mission file contains tasks in the expected parse format
  2. Run with --dry-run to validate parsing before execution
  3. Compare against a known-good mission file for the exact task syntax

Example fix

# before: mission.md has no recognizable task entries
# after: add tasks in the format parseMissionTasks recognizes, e.g.
## task: setup
- [ ] install deps
Defensive patterns

Strategy: validation

Validate before calling

const tasks = parseMissionTasks(await readFile(inputPath, 'utf-8'));
if (tasks.length === 0) failEarly('mission file has no tasks');

Type guard

const hasRunnableTasks = (tasks: MissionTask[]) => tasks.length > 0;

Prevention

When it happens

Trigger: A mission markdown file with no task sections/syntax the parser recognizes; malformed task headers; empty file.

Common situations: Wrong file passed (a README instead of the mission doc); mission format change so the parser no longer matches; indentation/formatting breaking task detection.

Related errors


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