{"record":{"id":"cf44a572c5a124d0","repo":"eyaltoledano/claude-task-master","slug":"branch-already-exists-branchname","errorCode":null,"errorMessage":"branch already exists: ${branchName}","messagePattern":"branch already exists: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/git/adapters/git-adapter.ts","lineNumber":403,"sourceCode":"\t *\n\t * @param {string} branchName - Name for the new branch\n\t * @param {Object} options - Branch creation options\n\t * @param {boolean} options.checkout - Whether to checkout after creation\n\t * @returns {Promise<void>}\n\t * @throws {Error} If branch already exists or working tree is dirty (when checkout=true)\n\t *\n\t * @example\n\t * await git.createBranch('feature-branch');\n\t * await git.createBranch('feature-branch', { checkout: true });\n\t */\n\tasync createBranch(\n\t\tbranchName: string,\n\t\toptions: { checkout?: boolean } = {}\n\t): Promise<void> {\n\t\t// Check if branch already exists\n\t\tconst exists = await this.branchExists(branchName);\n\t\tif (exists) {\n\t\t\tthrow new Error(`branch already exists: ${branchName}`);\n\t\t}\n\n\t\t// If checkout is requested, ensure working tree is clean\n\t\tif (options.checkout) {\n\t\t\tawait this.ensureCleanWorkingTree();\n\t\t}\n\n\t\t// Create the branch\n\t\tawait this.git.branch([branchName]);\n\n\t\t// Checkout if requested\n\t\tif (options.checkout) {\n\t\t\tawait this.git.checkout(branchName);\n\t\t}\n\t}\n\n\t/**\n\t * Checks out an existing branch.","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/git/adapters/git-adapter.ts#L385-L421","documentation":"createBranch() checks branchExists(branchName) first and throws when a branch with that exact name already exists locally. The library refuses to silently reuse or overwrite an existing branch. Operations on the new branch never start.","triggerScenarios":"Calling gitAdapter.createBranch('feature/x') when 'feature/x' already exists (previously created by this workflow, a teammate, or a retried run), regardless of the checkout option.","commonSituations":"Re-running an idempotency-unaware workflow after a partial failure; branch naming derived from a date/task that repeats; attempting to recreate a branch that was merged but not deleted.","solutions":["Check first with branchExists(name) and reuse or switch to the existing branch.","Delete the stale branch if unwanted: git branch -D feature/x (or adapter deleteBranch with force).","Use a unique branch name (append timestamp/task-id) to avoid collisions.","Make your automation idempotent: catch this error and treat 'already exists' as success."],"exampleFix":"// before\nawait git.createBranch('feature/x'); // throws if exists\n// after\nif (!(await git.branchExists('feature/x'))) {\n  await git.createBranch('feature/x', { checkout: true });\n} else {\n  await git.checkoutBranch('feature/x');\n}","handlingStrategy":"validation","validationCode":"if (await git.branchExists('feature/x')) {\n  // reuse, switch, or pick a new name before creating\n}","typeGuard":null,"tryCatchPattern":"try {\n  await git.createBranch('feature/x');\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('branch already exists')) {\n    await git.checkoutBranch('feature/x'); // idempotent fallback\n    return;\n  }\n  throw e;\n}","preventionTips":["Always branchExists() before createBranch() in automation.","Include a unique identifier (task ID, timestamp) in generated branch names.","Clean up merged branches regularly so names don't collide.","Make re-runs idempotent by treating 'already exists' as success."],"tags":["git","branch","conflict"],"backgroundTag":"branch-already-exists","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}