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

worktree_add_failed

worktree_add_failed

Error message

worktree_add_failed:${addArgs.join(' ')}

What it means

The spawned `git worktree add` exited non-zero and its stderr was empty (or the branch-in-use pattern did not match), so the library throws worktree_add_failed with the full argument list. This is the catch-all for git-side failures: bad refs, invalid paths, permission problems, corrupt git metadata, missing options on old git versions.

Source

Thrown at src/team/worktree.ts:471

    addArgs.push('--detach', plan.worktreePath, plan.baseRef);
  } else if (branchAlreadyExisted) {
    addArgs.push(plan.worktreePath, plan.branchName as string);
  } else {
    addArgs.push('-b', plan.branchName as string, plan.worktreePath, plan.baseRef);
  }

  const result = spawnSync('git', addArgs, {
    cwd: plan.repoRoot,
    encoding: 'utf-8',
      windowsHide: true,
    });

  if (result.status !== 0) {
    const stderr = (result.stderr || '').trim();
    if (plan.branchName && BRANCH_IN_USE_PATTERN.test(stderr)) {
      throw new Error(`branch_in_use:${plan.branchName}`);
    }
    throw new Error(stderr || `worktree_add_failed:${addArgs.join(' ')}`);
  }

  const ensured = {
    enabled: true,
    repoRoot: plan.repoRoot,
    worktreePath: resolve(plan.worktreePath),
    detached: plan.detached,
    branchName: plan.branchName,
    created: true,
    reused: false,
    createdBranch: Boolean(plan.branchName && !branchAlreadyExisted),
  } satisfies EnsureWorktreeResult;

  if (plan.branchName) {
    upsertCurrentTaskBaseline(plan.repoRoot, {
      branch_name: plan.branchName,
      worktree_path: ensured.worktreePath,
      base_ref: plan.baseRef,

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Reproduce manually: run the exact `git worktree add` command from the error message args in the repo to see the real git failure
  2. Verify the base ref exists: `git rev-parse --verify <ref>` before calling ensureWorktree
  3. Check git version and permissions: git --version and write access to repoRoot and the target path
  4. If stderr was genuinely empty due to a crash/timeout, retry once and capture result.stderr explicitly

Example fix

// before
ensureWorktree({ repoRoot, branchName: 'x', worktreePath, startPoint: 'origin/nope' }); // worktree_add_failed

// after
execSync('git rev-parse --verify origin/main'); // assert base ref first
ensureWorktree({ repoRoot, branchName: 'x', worktreePath, startPoint: 'origin/main' });
Defensive patterns

Strategy: try-catch

Validate before calling

import { execSync } from 'node:child_process';

function refExists(repoRoot: string, ref: string): boolean {
  try { execSync(`git rev-parse --verify ${ref}`, { cwd: repoRoot, stdio: 'ignore' }); return true; }
  catch { return false; }
}

Try / catch

try {
  ensureWorktree(plan);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('worktree_add_failed:')) {
    const args = e.message.slice('worktree_add_failed:'.length);
    // rerun `git worktree add ${args}` manually to capture real git stderr
  }
  throw e;
}

Prevention

When it happens

Trigger: ensureWorktree spawns `git worktree add <addArgs>` and git exits non-zero with no stderr captured — e.g. the base ref/commit does not exist, the target path is inside .git, the filesystem is read-only, or the installed git is too old to support a passed flag (like --orphan).

Common situations: Passing a start point like `origin/nonexistent-branch`; running as a user without write permission to the repo; git < 2.42 lacking --orphan support for worktrees; disk-full or read-only CI filesystems; detached-HEAD base with a bad HEAD sha.

Related errors


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