Yeachan-Heo/oh-my-codex · error · Error
invalid_worktree_branch
invalid_worktree_branch
Error message
invalid_worktree_branch:${branchName} What it means
Thrown when `git rev-parse --verify` for a planned branch name exits non-zero with no stderr, meaning the branch name is syntactically invalid or unverifiable as a git ref. The library validates the branch name before creating a worktree so that `git worktree add` doesn't fail later with a confusing error. The message embeds the offending branch name.
Source
Thrown at src/team/worktree.ts:112
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 validateBranchName(repoRoot: string, branchName: string): void {
const result = spawnSync('git', ['check-ref-format', '--branch', branchName], {
cwd: repoRoot,
encoding: 'utf-8',
windowsHide: true,
});
if (result.status === 0) return;
const stderr = (result.stderr || '').trim();
throw new Error(stderr || `invalid_worktree_branch:${branchName}`);
}
function branchExists(repoRoot: string, branchName: string): boolean {
const result = spawnSync('git', ['show-ref', '--verify', '--quiet', `refs/heads/${branchName}`], {
cwd: repoRoot,
encoding: 'utf-8',
});
return result.status === 0;
}
export function isWorktreeDirty(worktreePath: string): boolean {
const result = spawnSync('git', ['status', '--porcelain'], {
cwd: worktreePath,
encoding: 'utf-8',
windowsHide: true,
});
if (result.status !== 0) {
const stderr = (result.stderr || '').trim();View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Sanitize the branch name (and its components) with a token sanitizer, e.g. strip to [A-Za-z0-9._-], before calling the planner
- Check the composed name yourself with `git check-ref-format --branch <name>` and fail fast with a clear message
- Verify git is installed and on PATH (spawnSync('git',['--version'])) at startup
- If the name comes from user input, reject it early with a validation error instead of letting git validation throw
Example fix
// before
const branch = `${mode.name}/${workerName}`; // workerName = "john doe"
planWorktreeTarget({ branchName: branch, ... });
// after
const sanitize = (s: string) => s.trim().replace(/[^A-Za-z0-9._-]+/g, '-');
const branch = `${sanitize(mode.name)}/${sanitize(workerName)}`;
planWorktreeTarget({ branchName: branch, ... }); Defensive patterns
Strategy: validation
Validate before calling
import { spawnSync } from 'node:child_process';
function isValidBranchName(name: string): boolean {
if (!name || /[\s~^:?*[\]\\]/.test(name) || name.includes('..') ||
name.startsWith('-') || name.endsWith('.lock') || name.endsWith('/') || name.endsWith('.')) return false;
return spawnSync('git', ['check-ref-format', `refs/heads/${name}`], { encoding: 'utf-8' }).status === 0;
}
const ok = isValidBranchName(branch); Type guard
function isSafeBranchToken(s: unknown): s is string {
return typeof s === 'string' && /^[A-Za-z0-9._-]+$/.test(s) && !s.endsWith('.lock');
} Try / catch
catch (e) { if (String(e?.message).startsWith('invalid_worktree_branch:')) { /* sanitize name or prompt user */ } else throw e; } Prevention
- Sanitize all user-supplied components of branch names (worker, team, mode) to [A-Za-z0-9._-]
- Verify git is on PATH at startup before planning worktrees
- Add unit tests for branch-name composition with hostile inputs (spaces, unicode, '.lock')
When it happens
Trigger: Calling planWorktreeTarget/ensureWorktree with a branch name containing invalid ref characters (spaces, `..`, `~`, `^`, `:`, `?`, `*`, `[`, leading `-`, or trailing `.lock`), or a name that git refuses to resolve. Also occurs if the git spawn itself fails silently (git not installed) leaving empty stderr.
Common situations: Worker names or team names with spaces or slashes injected into branch names like `${mode.name}/${workerName}`; unicode/emoji in worker names; git missing from PATH so stderr is empty; names ending in `.lock`.
Related errors
- (result.stderr || '').trim() || `git ${args.join(' ')} faile
- (result.stderr || '').trim() || `git status failed for ${wor
- autoresearch_reset_requires_clean_worktree
- worktreeName must be a relative safe worktree name
- worktree_not_planned:${workerName}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/4fdd1e8d5216accd.
Report an issue: GitHub.