{"record":{"id":"b8a21dc1ea362bda","repo":"pcottle/learnGitBranching","slug":"fatal-a-branch-named-newname-already-exis","errorCode":null,"errorMessage":"fatal: A branch named ' + newName + ' already exists.","messagePattern":"fatal: A branch named ' \\+ newName \\+ ' already exists\\.","errorType":"exception","errorClass":"GitError","httpStatus":null,"severity":"error","filePath":"src/js/git/index.js","lineNumber":2836,"sourceCode":"  }\n\n  if (target.getIsRemote()) {\n    throw new GitError({\n      msg: intl.str('git-error-remote-branch')\n    });\n  }\n\n  newName = this.validateBranchName(newName);\n\n  if (this.doesRefExist(newName)) {\n    if (!force) {\n      throw new GitError({\n        msg: intl.todo(\"fatal: A branch named '\" + newName + \"' already exists.\")\n      });\n    }\n    var existing = this.resolveID(newName);\n    if (existing.get('type') !== 'branch') {\n      throw new GitError({\n        msg: intl.str('git-error-options')\n      });\n    }\n    if (this.HEAD.get('target') === existing) {\n      throw new GitError({\n        msg: intl.str('git-error-branch')\n      });\n    }\n    this.deleteBranch(existing);\n  }\n\n  var oldBranch = target;\n  var commitTarget = oldBranch.get('target');\n  var newBranch = this.makeBranch(newName, commitTarget);\n\n  if (oldBranch.get('remoteTrackingBranchID')) {\n    newBranch.set('remoteTrackingBranchID', oldBranch.get('remoteTrackingBranchID'));\n  }","sourceCodeStart":2818,"sourceCodeEnd":2854,"githubUrl":"https://github.com/pcottle/learnGitBranching/blob/5b09d0ff9678cad164f5a7488a279a44f90d7256/src/js/git/index.js#L2818-L2854","documentation":"Thrown by renameBranch(oldName, newName, force) when the new name already exists (doesRefExist) and force was not passed. Real git behaves identically: branch -m refuses to clobber an existing branch without -M/-f. Message is currently untranslated (intl.todo).","triggerScenarios":"renameBranch('a','b') without force=true while branch (or tag) 'b' already exists.","commonSituations":"Renaming onto main or another long-lived branch accidentally; scripting renames without checking targets; stale branch name collisions.","solutions":["Choose a fresh target name","Delete the conflicting branch first","Pass force=true (equivalent to git branch -M) — note it still refuses when the existing ref is not a branch or is checked out by HEAD"],"exampleFix":"// before\nengine.renameBranch('dev', 'main');\n// after\nengine.renameBranch('dev', 'main', true); // git branch -M","handlingStrategy":"validation","validationCode":"if (engine.doesRefExist(newName) && !force) { /* pass force=true or pick new name */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check doesRefExist(newName) before rename","Use force deliberately (git branch -M semantics)"],"tags":["git","branch","rename","name-conflict","force-flag"],"backgroundTag":"duplicate-git-ref-name","analyzedSha":"5b09d0ff9678cad164f5a7488a279a44f90d7256","analyzedAt":"2026-08-27T13:53:49.057Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}