{"record":{"id":"0fa1d68744bdaa23","repo":"Yeachan-Heo/oh-my-codex","slug":"mission-md-is-required-inside-mission-dir-missi","errorCode":null,"errorMessage":"mission.md is required inside mission-dir: ${missionFile}","messagePattern":"mission\\.md is required inside mission-dir: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/autoresearch/contracts.ts","lineNumber":224,"sourceCode":"  return {\n    pass: result.pass,\n    ...(result.score === undefined ? {} : { score: result.score }),\n  };\n}\n\nexport async function loadAutoresearchMissionContract(missionDirArg: string): Promise<AutoresearchMissionContract> {\n  const missionDir = resolve(missionDirArg);\n  if (!existsSync(missionDir)) {\n    throw contractError(`mission-dir does not exist: ${missionDir}`);\n  }\n\n  const repoRoot = readGit(missionDir, ['rev-parse', '--show-toplevel']);\n  ensurePathInside(repoRoot, missionDir);\n\n  const missionFile = join(missionDir, 'mission.md');\n  const sandboxFile = join(missionDir, 'sandbox.md');\n  if (!existsSync(missionFile)) {\n    throw contractError(`mission.md is required inside mission-dir: ${missionFile}`);\n  }\n  if (!existsSync(sandboxFile)) {\n    throw contractError(`sandbox.md is required inside mission-dir: ${sandboxFile}`);\n  }\n\n  const missionContent = await readFile(missionFile, 'utf-8');\n  const sandboxContent = await readFile(sandboxFile, 'utf-8');\n  const sandbox = parseSandboxContract(sandboxContent);\n  const missionRelativeDir = relative(repoRoot, missionDir) || basename(missionDir);\n  const missionSlug = slugifyMissionName(missionRelativeDir);\n\n  return {\n    missionDir,\n    repoRoot,\n    missionFile,\n    sandboxFile,\n    missionRelativeDir,\n    missionContent,","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/autoresearch/contracts.ts#L206-L242","documentation":"loadAutoresearchMissionContract requires a mission.md file directly inside the mission directory; if existsSync(join(missionDir,'mission.md')) fails it throws with the expected file path. mission.md carries the mission instructions and is mandatory alongside sandbox.md.","triggerScenarios":"A mission directory that contains only sandbox.md (or other files) but no mission.md; wrong file name such as mission.txt or Mission.md on case-sensitive filesystems.","commonSituations":"Authoring a new mission and forgetting the instructions file; case-sensitivity issues on Linux after developing on macOS/Windows; renamed files during refactors.","solutions":["Create mission.md inside the mission directory with the mission instructions.","Check exact casing/spelling: it must be 'mission.md'.","If templating missions, ensure the template includes both mission.md and sandbox.md."],"exampleFix":"# before\nmissions/m1/\n  sandbox.md\n\n# after\nmissions/m1/\n  mission.md\n  sandbox.md","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nif (!existsSync(join(missionDir, 'mission.md'))) {\n  throw new Error('mission.md missing — add mission instructions before loading');\n}\nconst contract = await loadAutoresearchMissionContract(missionDir);","typeGuard":null,"tryCatchPattern":"try {\n  await loadAutoresearchMissionContract(dir);\n} catch (err) {\n  if ((err as Error).message.includes('mission.md is required')) {\n    // create mission.md inside the mission dir (exact casing)\n  }\n  throw err;\n}","preventionTips":["Missions require both mission.md and sandbox.md — enforce with a template/scaffold command.","Watch filename casing across platforms (case-sensitive on Linux).","Include mission.md in git; check .gitignore."],"tags":["filesystem","mission-dir","missing-file"],"backgroundTag":"missing-required-file","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}