pcottle/learnGitBranching · error · GitError

fatal: not a branch:

Error message

fatal: not a branch: 

What it means

Thrown by the force-capable renameBranch(oldName, newName, force) when resolveID(oldName) returns null or something that is not a branch (tag, commit, HEAD). Mirrors git's 'fatal: not a branch' when branch -m is given a non-branch ref. Note the message is built with intl.todo so it is currently untranslated.

Source

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

  }

  if (numAway.length === 0) {
    throw new CommandResult({
      msg: foundTag
    });
  }

  // then join
  throw new CommandResult({
    msg: foundTag + '-' + numAway.length + '-g' + startCommit.get('id')
  });
};

GitEngine.prototype.renameBranch = function(oldName, newName, force) {
  var target = this.resolveID(oldName);

  if (!target || target.get('type') !== 'branch') {
    throw new GitError({
      msg: intl.todo('fatal: not a branch: ' + oldName)
    });
  }

  if (target.getIsRemote()) {
    throw new GitError({
      msg: intl.str('git-error-remote-branch')
    });
  }

  newName = this.validateBranchName(newName);

  if (this.doesRefExist(newName)) {
    if (!force) {
      throw new GitError({
        msg: intl.todo("fatal: A branch named '" + newName + "' already exists.")
      });
    }

View on GitHub (pinned to 5b09d0ff96)

Solutions

  1. Confirm the ref exists and is a local branch (this.resolveID(name).get('type') === 'branch') before renaming
  2. Fix typos in the branch name
  3. For tags/commits, use the appropriate command instead of rename

Example fix

// before
engine.renameBranch('featr', 'feature'); // typo
// after
engine.renameBranch('feat', 'feature');
Defensive patterns

Strategy: type-guard

Validate before calling

var t = engine.resolveID(oldName);
if (!t || t.get('type') !== 'branch') { /* bail or fix name */ }

Type guard

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

Try / catch

try { engine.renameBranch(a, b, f); } catch (e) { if (e instanceof GitError && /^fatal: not a branch/.test(e.msg)) { /* handle */ } else throw e; }

Prevention

When it happens

Trigger: renameBranch(name,...) where the first arg fails to resolve or resolves to a non-branch ref — e.g. renaming a tag, a commit sha, or a misspelled branch name.

Common situations: Typos in the source branch name; passing a tag or commit id to branch -m; scripted renames that assume a branch exists after it was deleted.

Related errors


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