{"record":{"id":"89854d8fcf8c3d61","repo":"Yeachan-Heo/oh-my-codex","slug":"no-runnable-mission-tasks-found-in-parsed-file","errorCode":null,"errorMessage":"No runnable mission tasks found in ${parsed.file}.","messagePattern":"No runnable mission tasks found in (.+?)\\.","errorType":"validation","errorClass":"MissionCommandError","httpStatus":null,"severity":"error","filePath":"src/cli/mission.ts","lineNumber":439,"sourceCode":"      await runSelectedTasks(summary, paths, parsed, now, stdout, runTask, shouldRun);\n      summary.status = missionStatus(summary.tasks);\n      summary.completed_at = now().toISOString();\n      summary.counts = missionCounts(summary.tasks);\n      await persistSummary(paths.summaryPath, summary);\n      await appendLedger(paths.ledgerPath, { event: \"mission_completed\", at: summary.completed_at, slug: summary.slug, status: summary.status, counts: summary.counts });\n      if (parsed.json) stdout(JSON.stringify({ ok: summary.status === \"passed\", summary_path: paths.summaryPath, ledger_path: paths.ledgerPath, summary }, null, 2));\n      else {\n        stdout(`mission ${parsed.action} ${summary.status}: ${summary.slug}`);\n        stdout(`summary: ${paths.summaryPath}`);\n        stdout(`ledger: ${paths.ledgerPath}`);\n      }\n      if (summary.status !== \"passed\") process.exitCode = 1;\n      return;\n    }\n\n    const input = await readFile(paths.inputPath, \"utf-8\");\n    const tasks = parseMissionTasks(input);\n    if (tasks.length === 0) throw new MissionCommandError(`No runnable mission tasks found in ${parsed.file}.`);\n\n    const startedAt = now().toISOString();\n    const summary: MissionSummary = {\n      version: 1,\n      slug: paths.slug,\n      input_path: paths.inputPath,\n      dry_run: parsed.dryRun,\n      continue_on_error: parsed.continueOnError,\n      started_at: startedAt,\n      status: parsed.dryRun ? \"planned\" : \"running\",\n      counts: missionCounts(tasks),\n      codex_args: parsed.codexArgs,\n      tasks,\n    };\n\n    if (parsed.dryRun) {\n      for (const task of summary.tasks) task.status = \"planned\";\n      summary.counts = missionCounts(summary.tasks);","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/mission.ts#L421-L457","documentation":"During mission run, the input file was read and parsed by parseMissionTasks but produced zero tasks. The mission file contains no runnable task entries.","triggerScenarios":"A mission markdown file with no task sections/syntax the parser recognizes; malformed task headers; empty file.","commonSituations":"Wrong file passed (a README instead of the mission doc); mission format change so the parser no longer matches; indentation/formatting breaking task detection.","solutions":["Check the mission file contains tasks in the expected parse format","Run with --dry-run to validate parsing before execution","Compare against a known-good mission file for the exact task syntax"],"exampleFix":"# before: mission.md has no recognizable task entries\n# after: add tasks in the format parseMissionTasks recognizes, e.g.\n## task: setup\n- [ ] install deps","handlingStrategy":"validation","validationCode":"const tasks = parseMissionTasks(await readFile(inputPath, 'utf-8'));\nif (tasks.length === 0) failEarly('mission file has no tasks');","typeGuard":"const hasRunnableTasks = (tasks: MissionTask[]) => tasks.length > 0;","tryCatchPattern":null,"preventionTips":["Run --dry-run in CI to validate mission files","Lint mission docs for task syntax before executing"],"tags":["mission","empty-input","parser"],"backgroundTag":"empty-input-collection","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}