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

sandbox.md is required inside mission-dir: ${sandboxFile}

Error message

sandbox.md is required inside mission-dir: ${sandboxFile}

What it means

loadAutoresearchMissionContract requires a sandbox.md file directly inside the mission directory; if existsSync(join(missionDir,'sandbox.md')) fails it throws with the expected path. sandbox.md defines the evaluator contract (frontmatter with evaluator.command and evaluator.format=json) plus sandbox body.

Source

Thrown at src/autoresearch/contracts.ts:227

  };
}

export async function loadAutoresearchMissionContract(missionDirArg: string): Promise<AutoresearchMissionContract> {
  const missionDir = resolve(missionDirArg);
  if (!existsSync(missionDir)) {
    throw contractError(`mission-dir does not exist: ${missionDir}`);
  }

  const repoRoot = readGit(missionDir, ['rev-parse', '--show-toplevel']);
  ensurePathInside(repoRoot, missionDir);

  const missionFile = join(missionDir, 'mission.md');
  const sandboxFile = join(missionDir, 'sandbox.md');
  if (!existsSync(missionFile)) {
    throw contractError(`mission.md is required inside mission-dir: ${missionFile}`);
  }
  if (!existsSync(sandboxFile)) {
    throw contractError(`sandbox.md is required inside mission-dir: ${sandboxFile}`);
  }

  const missionContent = await readFile(missionFile, 'utf-8');
  const sandboxContent = await readFile(sandboxFile, 'utf-8');
  const sandbox = parseSandboxContract(sandboxContent);
  const missionRelativeDir = relative(repoRoot, missionDir) || basename(missionDir);
  const missionSlug = slugifyMissionName(missionRelativeDir);

  return {
    missionDir,
    repoRoot,
    missionFile,
    sandboxFile,
    missionRelativeDir,
    missionContent,
    sandboxContent,
    sandbox,
    missionSlug,

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Create sandbox.md in the mission directory with valid frontmatter (evaluator.command, evaluator.format: json).
  2. Verify exact filename casing 'sandbox.md'.
  3. Ensure sandbox.md is committed and not ignored by .gitignore.

Example fix

# before
missions/m1/
  mission.md

# after
missions/m1/
  mission.md
  sandbox.md  # ---\nevaluator:\n  command: ./evaluate.sh\n  format: json\n---
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
import { join } from 'node:path';

if (!existsSync(join(missionDir, 'sandbox.md'))) {
  throw new Error('sandbox.md missing — add evaluator frontmatter (evaluator.command, format: json)');
}
const contract = await loadAutoresearchMissionContract(missionDir);

Try / catch

try {
  await loadAutoresearchMissionContract(dir);
} catch (err) {
  if ((err as Error).message.includes('sandbox.md is required')) {
    // create sandbox.md with valid evaluator frontmatter in the mission dir
  }
  throw err;
}

Prevention

When it happens

Trigger: Mission directory missing sandbox.md entirely; file named sandbox.txt or with different casing on a case-sensitive filesystem.

Common situations: New missions authored with only mission.md; files renamed or excluded by .gitignore so they are missing after clone; casing mistakes across operating systems.

Related errors


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