Yeachan-Heo/oh-my-codex · error · Error
mission-dir must be inside a git repository.
Error message
mission-dir must be inside a git repository.
What it means
ensurePathInside throws MISSION_DIR_GIT_ERROR ('mission-dir must be inside a git repository.') when the mission directory resolved by loadAutoresearchMissionContract is not contained within the repository root reported by git rev-parse --show-toplevel. This guards against mission dirs that escape the repo (absolute paths outside, or on a different filesystem branch).
Source
Thrown at src/autoresearch/contracts.ts:79
? err.stderr.toString('utf-8').trim()
: '';
throw contractError(stderr || MISSION_DIR_GIT_ERROR);
}
}
export function slugifyMissionName(value: string): string {
return value
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '')
.slice(0, 48) || 'mission';
}
function ensurePathInside(parentPath: string, childPath: string): void {
const rel = relative(parentPath, childPath);
if (rel === '' || (!rel.startsWith('..') && rel !== '..')) return;
throw contractError(MISSION_DIR_GIT_ERROR);
}
function extractFrontmatter(content: string): { frontmatter: string; body: string } {
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
if (!match) {
throw contractError(SANDBOX_FRONTMATTER_ERROR);
}
return {
frontmatter: match[1] || '',
body: (match[2] || '').trim(),
};
}
function parseSimpleYamlFrontmatter(frontmatter: string): Record<string, unknown> {
const result: Record<string, unknown> = {};
let currentSection: string | null = null;
for (const rawLine of frontmatter.split(/\r?\n/)) {View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Move or copy the mission directory inside the git work tree and pass that path.
- Avoid symlinked mission dirs; pass the real path inside the repo.
- For worktrees/submodules, ensure the mission dir is inside the toplevel that git rev-parse --show-toplevel actually reports.
- Check for typos in the mission-dir argument that resolve to a path outside the repo.
Example fix
// before
await loadAutoresearchMissionContract('/elsewhere/missions/m1');
// after
await loadAutoresearchMissionContract('missions/m1'); // inside the repo root Defensive patterns
Strategy: validation
Validate before calling
import { relative, resolve } from 'node:path';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const execFileAsync = promisify(execFile);
async function assertMissionInsideRepo(missionDir: string): Promise<void> {
const { stdout } = await execFileAsync('git', ['-C', missionDir, 'rev-parse', '--show-toplevel']);
const rel = relative(stdout.trim(), resolve(missionDir));
if (rel === '' || rel.startsWith('..')) throw new Error('mission dir outside repo');
} Try / catch
try {
await loadAutoresearchMissionContract(dir);
} catch (err) {
if ((err as Error).message.includes('inside a git repository')) {
// move mission dir into the repo or fix symlink/worktree layout
}
throw err;
} Prevention
- Always pass mission dirs located under the git work tree.
- Avoid symlinked mission directories.
- For worktrees/submodules, resolve the real path before passing it.
When it happens
Trigger: readGit succeeds but the relative path from repoRoot to missionDir starts with '..' (or equals '..'), e.g. the mission dir is a sibling/parent of the repo root, a symlink pointing outside, or git reports a different toplevel than expected (worktree/submodule mismatch).
Common situations: Passing an absolute path to a mission folder that lies outside the repo; symlinks into the repo (git resolves the real toplevel, so the symlinked path computes as outside); mismatched submodule/worktree setups where the reported toplevel differs from the mission dir's location.
Related errors
- ${stderr || MISSION_DIR_GIT_ERROR}
- mission-dir does not exist: ${missionDir}
- No autoresearch-goal mission found at ${repoRelative(cwd, pa
- Invalid autoresearch-goal mission at ${repoRelative(cwd, pat
- Autoresearch goal ${mission.slug} is already complete; creat
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/d565c40775b4df2e.
Report an issue: GitHub.