Yeachan-Heo/oh-my-codex · error · Error
${stderr || MISSION_DIR_GIT_ERROR}
Error message
${stderr || MISSION_DIR_GIT_ERROR} What it means
Thrown by readGit in src/autoresearch/contracts.ts when a git subprocess it runs (e.g. git rev-parse --show-toplevel) fails. The error message is the trimmed stderr from git if available, otherwise the generic MISSION_DIR_GIT_ERROR message. This surfaces git invocation failures such as not being inside a repository or git not being installed.
Source
Thrown at src/autoresearch/contracts.ts:63
return new Error(message);
}
function readGit(repoPath: string, args: string[]): string {
try {
return execFileSync('git', args, {
cwd: repoPath,
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'pipe'],
windowsHide: true,
}).trim();
} catch (error) {
const err = error as NodeJS.ErrnoException & { stderr?: string | Buffer };
const stderr = typeof err.stderr === 'string'
? err.stderr.trim()
: err.stderr instanceof Buffer
? 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);
}
View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Verify the mission directory is inside a git repository: run git rev-parse --show-toplevel in it.
- If git is missing, install git or ensure it is on PATH for the process.
- If git printed stderr (e.g. 'detected dubious ownership'), fix accordingly — e.g. git config --global --add safe.directory <path>.
- Initialize a repo (git init) if the mission folder was meant to be standalone.
Example fix
// before
const contract = await loadAutoresearchMissionContract('/plain/folder/mission');
// after
await exec('git -C /plain/folder init'); // or move mission inside an existing repo
const contract = await loadAutoresearchMissionContract('/plain/folder/mission'); Defensive patterns
Strategy: try-catch
Validate before calling
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const execFileAsync = promisify(execFile);
async function assertGitRepoAvailable(dir: string): Promise<void> {
await execFileAsync('git', ['-C', dir, 'rev-parse', '--show-toplevel'], { timeout: 5000 });
} Try / catch
try {
const contract = await loadAutoresearchMissionContract(missionDir);
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
if (msg.includes('git') || msg === MISSION_DIR_GIT_ERROR) {
// surface git stderr, suggest git init / PATH / safe.directory fixes
}
throw err;
} Prevention
- Run 'git rev-parse --show-toplevel' in the mission dir as a preflight.
- Ensure git is installed and on PATH in CI images.
- Configure safe.directory for mounted/shared repos.
When it happens
Trigger: loadAutoresearchMissionContract -> readGit(missionDir, ['rev-parse','--show-toplevel']) when the mission directory is not inside a git work tree, git is not on PATH, or git exits non-zero for another reason (permissions, corrupt repo).
Common situations: Pointing --mission-dir at a plain folder that was never git-inited; running in a container/CI image without git; a .git directory with broken ownership ('dubious ownership' safe.directory errors).
Related errors
- mission-dir must be inside a git repository.
- stderr || `git ${args.join(' ')} failed`
- (result.stderr || '').trim() || `git ${args.join(' ')} faile
- worktree_add_failed
- No autoresearch-goal mission found at ${repoRelative(cwd, pa
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/eca7cab42dd9da6e.
Report an issue: GitHub.