{"record":{"id":"4d37b78c035db198","repo":"can1357/oh-my-pi","slug":"local-branch-localbranch-already-exists-at-fo","errorCode":null,"errorMessage":"local branch ${localBranch} already exists at ${formatShortSha(existingOid ?? undefined) ?? existingOid ?? \"unknown commit\"}; pass force=true to reset it","messagePattern":"local branch (.+?) already exists at (.+?); pass force=true to reset it","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/gh-pr-checkout.ts","lineNumber":451,"sourceCode":"\t\t\tconst existingWorktree = existingWorktrees.find(entry => entry.branch === toLocalBranchRef(localBranch));\n\n\t\t\tconst remote = await ensurePrRemoteWithRepo(repoRoot, data, repository, signal);\n\t\t\tawait repository.fetch(\n\t\t\t\tremote.name,\n\t\t\t\t`refs/heads/${headRefName}`,\n\t\t\t\t`refs/remotes/${remote.name}/${headRefName}`,\n\t\t\t\tPR_FETCH_TIMEOUT_MS,\n\t\t\t\tsignal,\n\t\t\t);\n\n\t\t\tif (!existingWorktree) {\n\t\t\t\tconst localBranchRef = toLocalBranchRef(localBranch);\n\t\t\t\tconst localBranchExists = await repository.refExists(localBranchRef, signal);\n\t\t\t\tif (localBranchExists) {\n\t\t\t\t\tconst existingOid = await repository.resolveRef(localBranchRef, signal);\n\t\t\t\t\tif (existingOid !== headRefOid) {\n\t\t\t\t\t\tif (!force) {\n\t\t\t\t\t\t\tthrow new ToolError(\n\t\t\t\t\t\t\t\t`local branch ${localBranch} already exists at ${formatShortSha(existingOid ?? undefined) ?? existingOid ?? \"unknown commit\"}; pass force=true to reset it`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait repository.createBranch(\n\t\t\t\t\t\t\tlocalBranch,\n\t\t\t\t\t\t\t`refs/remotes/${remote.name}/${headRefName}`,\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tawait repository.createBranch(localBranch, `refs/remotes/${remote.name}/${headRefName}`, false, signal);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst configPrefix = `branch.${localBranch}.`;\n\t\t\tawait repository.configSet(`${configPrefix}remote`, remote.name, signal);","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/gh-pr-checkout.ts#L433-L469","documentation":"When checking out a PR, the tool wants to create local branch <localBranch>. If that branch already exists and points at a different commit than the PR head (headRefOid), creating it would either fail or silently diverge, so without force=true the tool throws and tells you the existing commit and how to override.","triggerScenarios":"Running op pr_checkout twice for the same PR after the PR gained new commits (local branch still at old head); a pre-existing branch with the same conventional name (e.g. `pr/123` or the head branch name) from another source; a stale checkout from a previous session.","commonSituations":"Re-checking out an actively updated PR; name collision with a user's own branch; reusing a repo where someone branched locally with the same name.","solutions":["Re-run the checkout with force=true (force option) to reset the existing local branch to the PR head commit — but first confirm you have no unpushed local commits on that branch you need.","If the local branch has your own work, rename it first: `git branch -m <localBranch> <localBranch>-backup`, then check out the PR again.","Compare the commits before forcing: `git log <localBranch>..HEAD` / check the existing SHA from the message to decide whether resetting loses anything."],"exampleFix":"// before: second checkout of PR 123 after new upstream commits\n// ToolError: local branch pr/123 already exists at abc1234; pass force=true\n// after\nop pr_checkout 1234 force=true   // resets pr/123 to new head\ngit branch -m pr/123 pr/123-old  // ...or preserve local work first","handlingStrategy":"validation","validationCode":"const branchRef = `refs/heads/${localBranch}`;\nif (await repo.refExists(branchRef)) {\n  const oid = await repo.resolveRef(branchRef);\n  if (oid !== prHeadOid && !hasUnpushedWork(branchRef)) {\n    // safe to force-reset\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await op.prCheckout({ prRef, force: false });\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"already exists\")) {\n    await git.branch([\"-m\", localBranch, `${localBranch}-backup`]); // preserve, then retry\n    await op.prCheckout({ prRef });\n  } else throw err;\n}","preventionTips":["Before re-checkout, check for unpushed commits on the existing branch.","Rename or delete stale pr/* branches after merging.","Avoid creating personal branches named like the tool's PR branches (pr/<N>).","Only pass force=true after confirming the existing branch holds nothing unique."],"tags":["git","branch-conflict","pr-checkout"],"backgroundTag":"branch-already-exists","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}