{"record":{"id":"6693cb5f2a0bf515","repo":"Yeachan-Heo/oh-my-codex","slug":"worktree-path-conflict","errorCode":"worktree_path_conflict","errorMessage":"worktree_path_conflict:${plan.worktreePath}","messagePattern":"worktree_path_conflict:(.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/worktree.ts","lineNumber":437,"sourceCode":"      reused: true,\n      createdBranch: false,\n      ...(dirty ? { dirty: true } : {}),\n    } satisfies EnsureWorktreeResult;\n\n    if (plan.branchName) {\n      upsertCurrentTaskBaseline(plan.repoRoot, {\n        branch_name: plan.branchName,\n        worktree_path: reused.worktreePath,\n        base_ref: plan.baseRef,\n        status: 'active',\n      });\n    }\n\n    return reused;\n  }\n\n  if (existsSync(plan.worktreePath)) {\n    throw new Error(`worktree_path_conflict:${plan.worktreePath}`);\n  }\n\n  if (plan.branchName && hasBranchInUse(allWorktrees, plan.branchName, plan.worktreePath)) {\n    throw new Error(`branch_in_use:${plan.branchName}`);\n  }\n\n  if (plan.branchName) {\n    assertCurrentTaskBranchAvailable(plan.repoRoot, plan.branchName, plan.worktreePath);\n  }\n\n  mkdirSync(dirname(plan.worktreePath), { recursive: true });\n  const branchAlreadyExisted = plan.branchName ? branchExists(plan.repoRoot, plan.branchName) : false;\n\n  const addArgs = ['worktree', 'add'];\n  if (plan.detached) {\n    addArgs.push('--detach', plan.worktreePath, plan.baseRef);\n  } else if (branchAlreadyExisted) {\n    addArgs.push(plan.worktreePath, plan.branchName as string);","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/worktree.ts#L419-L455","documentation":"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`.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove or rename the existing directory: rm -rf <plan.worktreePath> then retry ensureWorktree","Run `git worktree prune` in the repo root to clear stale worktree metadata and retry","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","Change the plan's branchName/slug so the derived worktreePath is unique per concurrent run"],"exampleFix":"// before\nconst ensured = ensureWorktree({ repoRoot, branchName: 'fix', worktreePath: '.worktrees/fix' }); // dir exists -> worktree_path_conflict\n\n// after\nexecSync('git worktree prune', { cwd: repoRoot });\nif (existsSync(worktreePath)) rmSync(worktreePath, { recursive: true, force: true });\nconst ensured = ensureWorktree({ repoRoot, branchName: 'fix', worktreePath: '.worktrees/fix' });","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nfunction ensureWorktreePathFree(worktreePath: string): boolean {\n  return !existsSync(resolve(worktreePath));\n}","typeGuard":null,"tryCatchPattern":"try {\n  ensureWorktree(plan);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('worktree_path_conflict:')) {\n    // stale dir: prune/remove then retry once\n  } else throw e;\n}","preventionTips":["Derive worktree paths from unique branch names or run ids","Always tear down worktrees in a finally block, including on signal/timeout","Run git worktree prune before provisioning in CI"],"tags":["git","worktree","filesystem","conflict"],"backgroundTag":"worktree-path-already-exists","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}