Yeachan-Heo/oh-my-codex · error · Error
stderr || `git ${args.join(' ')} failed`
Error message
stderr || `git ${args.join(' ')} failed` What it means
readGit wraps git subprocess execution and rethrows with the git command's trimmed stderr (or a generic 'git <args> failed' message when stderr is empty). It surfaces any failure of an async git invocation, such as rev-parse, branch lookups, or path exclusions.
Source
Thrown at src/autoresearch/runtime.ts:175
return trimmed.length <= max ? trimmed : `${trimmed.slice(0, max)}\n...`;
}
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 new Error(stderr || `git ${args.join(' ')} failed`);
}
}
function tryResolveGitCommit(worktreePath: string, ref: string): string | null {
const result = spawnSync('git', ['rev-parse', '--verify', `${ref}^{commit}`], {
cwd: worktreePath,
encoding: 'utf-8',
});
if (result.status !== 0) return null;
const resolved = (result.stdout || '').trim();
return resolved || null;
}
async function writeGitInfoExclude(worktreePath: string, pattern: string): Promise<void> {
const excludePath = readGit(worktreePath, ['rev-parse', '--git-path', 'info/exclude']);
const existing = existsSync(excludePath)
? await readFile(excludePath, 'utf-8')
: '';View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Run the printed git command manually in the same cwd to see the real failure
- Verify the working directory is a valid git repository and the ref/commit exists (git rev-parse <ref>)
- Check git is installed and on PATH in the execution environment (CI containers, nix shells)
- For auth failures in CI, configure credentials or run with a token that can read the repo
Example fix
// before
const head = await readGit(repoRoot, ['rev-parse', 'HEAD']); // throws 'unknown revision...'
// after
// ensure repo has at least one commit
await run('git', ['commit', '--allow-empty', '-m', 'init'], { cwd: repoRoot });
const head = await readGit(repoRoot, ['rev-parse', 'HEAD']); Defensive patterns
Strategy: try-catch
Validate before calling
import { spawnSync } from 'node:child_process';
function gitAvailable(cwd: string): boolean {
return spawnSync('git', ['rev-parse', '--is-inside-work-tree'], { cwd }).status === 0;
} Try / catch
try { const sha = await readGit(cwd, ['rev-parse', 'HEAD']); }
catch (e) { if (e instanceof Error && /git .* failed|fatal:/.test(e.message)) { /* surface git stderr, validate repo state */ } throw e; } Prevention
- Verify the directory is a git repository before invoking autoresearch runtime APIs
- Pre-check refs with git rev-parse --verify before passing them to readGit-based helpers
- Ensure git is on PATH in CI/containers
When it happens
Trigger: Any async git invocation failing: missing ref/commit (rev-parse on an unknown SHA), detached/missing branch, not inside a git repository, git not on PATH for the async execution environment, or permission problems on the repo.
Common situations: Running autoresearch in a directory that is not a git worktree, referencing a commit that was garbage-collected, shallow clones missing expected history, or CI environments where git auth/config blocks the command.
Related errors
- (result.stderr || '').trim() || `git ${args.join(' ')} faile
- editor exited with status ${result.status ?? 'unknown'}
- worktree_add_failed
- ${stderr || MISSION_DIR_GIT_ERROR}
- (result.stderr || '').trim() || `git status failed for ${wor
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/f9a2a21b0a9bf321.
Report an issue: GitHub.