pcottle/learnGitBranching · error · GitError

You cannot delete main branch on remote!

Error message

You cannot delete main branch on remote!

What it means

The remote's main branch is protected: pushDeleteRemoteBranch refuses to delete a remote ref whose id is 'main'. Real hosting services (GitHub, GitLab) similarly protect the default branch from deletion.

Source

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

  // HAX HAX update main and remote tracking for main
  chain = chain.then(function() {
    var localCommit = this.getCommitFromRef(sourceLocation);
    this.setTargetLocation(this.resolveID(ORIGIN_PREFIX + options.destination), localCommit);
    return this.animationFactory.playRefreshAnimation(this.gitVisuals);
  }.bind(this));

  if (!options.dontResolvePromise) {
    this.animationQueue.thenFinish(chain);
  }
};

GitEngine.prototype.pushDeleteRemoteBranch = function(
  remoteBranch,
  branchOnRemote
) {
  if (branchOnRemote.get('id') === 'main') {
    throw new GitError({
      msg: intl.todo('You cannot delete main branch on remote!')
    });
  }
  // ok so this isn't too bad -- we basically just:
  // 1) instruct the remote to delete the branch
  // 2) kill off the remote branch locally
  // 3) find any branches tracking this remote branch and set them to not track
  var id = remoteBranch.get('id');
  this.origin.deleteBranch(branchOnRemote);
  this.deleteBranch(remoteBranch);
  this.branchCollection.each(function(branch) {
    if (branch.getRemoteTrackingBranchID() === id) {
      branch.setRemoteTrackingBranchID(null);
    }
  }, this);

  // animation needs to be triggered on origin directly
  this.origin.pruneTree();

View on GitHub (pinned to 5b09d0ff96)

Solutions

  1. Delete a non-default branch instead
  2. If the remote truly must be reset, force-push main to an earlier commit rather than deleting it
  3. Filter 'main' out of any branch-deletion loops

Example fix

// before
git push origin :main
// after
git push origin :feature
Defensive patterns

Strategy: validation

Validate before calling

if (branchOnRemote.get('id') === 'main') throw new Error('refusing to delete main');

Type guard

function isProtectedBranch(ref) { return ref.get('id') === 'main'; }

Prevention

When it happens

Trigger: Calling git push origin :main (or the push API with a delete intent) where branchOnRemote.get('id') === 'main'.

Common situations: Trying to clean up 'all' remote branches with a wildcard delete; level scripts iterating remote refs for deletion.

Related errors


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