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

worktree_path_conflict

worktree_path_conflict

Error message

worktree_path_conflict:${plan.worktreePath}

What it means

Thrown by ensureWorktree when the target directory for a new git worktree already exists on disk. The library refuses to clobber an existing path because it cannot know whether it holds unrelated files or a stale worktree. This is a pre-flight safety check performed before running `git worktree add`.

Source

Thrown at src/team/worktree.ts:437

      reused: true,
      createdBranch: false,
      ...(dirty ? { dirty: true } : {}),
    } satisfies EnsureWorktreeResult;

    if (plan.branchName) {
      upsertCurrentTaskBaseline(plan.repoRoot, {
        branch_name: plan.branchName,
        worktree_path: reused.worktreePath,
        base_ref: plan.baseRef,
        status: 'active',
      });
    }

    return reused;
  }

  if (existsSync(plan.worktreePath)) {
    throw new Error(`worktree_path_conflict:${plan.worktreePath}`);
  }

  if (plan.branchName && hasBranchInUse(allWorktrees, plan.branchName, plan.worktreePath)) {
    throw new Error(`branch_in_use:${plan.branchName}`);
  }

  if (plan.branchName) {
    assertCurrentTaskBranchAvailable(plan.repoRoot, plan.branchName, plan.worktreePath);
  }

  mkdirSync(dirname(plan.worktreePath), { recursive: true });
  const branchAlreadyExisted = plan.branchName ? branchExists(plan.repoRoot, plan.branchName) : false;

  const addArgs = ['worktree', 'add'];
  if (plan.detached) {
    addArgs.push('--detach', plan.worktreePath, plan.baseRef);
  } else if (branchAlreadyExisted) {
    addArgs.push(plan.worktreePath, plan.branchName as string);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Remove or rename the existing directory: rm -rf <plan.worktreePath> then retry ensureWorktree
  2. Run `git worktree prune` in the repo root to clear stale worktree metadata and retry
  3. If the directory is a valid existing worktree you want to reuse, route the call through the reuse path (the code just above returns `reused`) instead of the create path
  4. Change the plan's branchName/slug so the derived worktreePath is unique per concurrent run

Example fix

// before
const ensured = ensureWorktree({ repoRoot, branchName: 'fix', worktreePath: '.worktrees/fix' }); // dir exists -> worktree_path_conflict

// after
execSync('git worktree prune', { cwd: repoRoot });
if (existsSync(worktreePath)) rmSync(worktreePath, { recursive: true, force: true });
const ensured = ensureWorktree({ repoRoot, branchName: 'fix', worktreePath: '.worktrees/fix' });
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
import { resolve } from 'node:path';

function ensureWorktreePathFree(worktreePath: string): boolean {
  return !existsSync(resolve(worktreePath));
}

Try / catch

try {
  ensureWorktree(plan);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('worktree_path_conflict:')) {
    // stale dir: prune/remove then retry once
  } else throw e;
}

Prevention

When it happens

Trigger: Calling ensureWorktree with a plan whose plan.worktreePath resolves to an existing directory — e.g. a previous worktree was left behind without `git worktree prune`, or a crashed run did not clean up its .worktrees/<slug> directory, or two plans computed the same path slug.

Common situations: Concurrent team runs deriving the same worktree path; leftover directories after a hard kill (SIGKILL, CI timeout) between add and cleanup; manually created directories colliding with the worktree naming scheme; stale worktree metadata after the branch was deleted outside the tool.

Related errors


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