pcottle/learnGitBranching · error · GitError

git-error-branch

Error message

git-error-branch

What it means

Thrown by the first (legacy) renameBranch implementation when the resolved ref for the old branch name is not a local branch (e.g. it resolved to a commit, tag, or HEAD) or when it is a remote tracking branch (o/*). Git refuses to rename anything that is not a local branch, and the simulator mirrors that behavior by throwing a GitError with the localized 'git-error-branch' message.

Source

Thrown at src/js/git/index.js:2732

};

GitEngine.prototype.branch = function(name, ref) {
  var target = this.getCommitFromRef(ref);
  var newBranch = this.validateAndMakeBranch(name, target);

  ref = this.resolveID(ref);
  if (this.isRemoteBranchRef(ref)) {
    this.setLocalToTrackRemote(newBranch, ref);
  }
};

GitEngine.prototype.renameBranch = function(oldName, newName) {
  oldName = this.crappyUnescape(oldName);
  newName = this.validateBranchName(newName);

  var branch = this.resolveID(oldName);
  if (branch.get('type') !== 'branch' || branch.getIsRemote()) {
    throw new GitError({
      msg: intl.str('git-error-branch')
    });
  }

  if (this.doesRefExist(newName)) {
    throw new GitError({
      msg: intl.str(
        'bad-branch-name',
        { branch: newName }
      )
    });
  }

  delete this.refs[oldName];
  branch.set('id', newName);
  this.refs[newName] = branch;
};

View on GitHub (pinned to 5b09d0ff96)

Solutions

  1. Verify the old name is an existing local branch (git branch output) before renaming
  2. If you meant a remote branch, create a new local branch instead of renaming the remote ref
  3. Check for typos/hashes/tags passed as the old branch name

Example fix

// before
engine.renameBranch('o/main', 'main2');
// after
engine.renameBranch('main', 'main2');
Defensive patterns

Strategy: validation

Validate before calling

var ref = engine.resolveID(oldName);
if (!ref || ref.get('type') !== 'branch' || ref.getIsRemote()) {
  // pick another name or bail
}

Type guard

function isLocalBranch(engine, name) {
  var r = engine.resolveID(name);
  return !!r && r.get('type') === 'branch' && !r.getIsRemote();
}

Try / catch

try { engine.renameBranch(a, b); } catch (e) { if (e instanceof GitError && e.msg === intl.str('git-error-branch')) { /* handle */ } else throw e; }

Prevention

When it happens

Trigger: Calling the engine's renameBranch('foo','bar') where 'foo' resolves via resolveID to a non-branch ref (a tag, a commit id, HEAD) or to a remote branch (getIsRemote() true). Typically reached from a 'git branch -m foo bar' command when foo does not exist as a local branch.

Common situations: Typos in the old branch name; renaming a remote tracking branch like o/main; trying to rename a tag; using a commit hash as the first argument.

Related errors


AI-assisted analysis of pcottle/learnGitBranching@5b09d0ff96 (2026-08-27). Data as JSON: /api/errors/4603868594a8547e. Report an issue: GitHub.