gitbutlerapp/gitbutler · error

failed to push {} of {} branch{}

Error message

failed to push {} of {} branch{}

What it means

`but push` pushes each selected branch and aggregates per-branch results. Failed branches are printed with their branch name and underlying error (auth failure, unreachable remote, remote rejection, force-push protection tripping), then the command bails with this summary so the process exits non-zero. An up-to-date workspace with nothing to push is explicitly not an error.

Source

Thrown at crates/but/src/command/legacy/push.rs:838

                    "branch"
                } else {
                    "branches"
                }
            )?;
            for failed in &failed_branches {
                writeln!(
                    human,
                    "    {} - {}",
                    t.error.paint(&failed.branch_name),
                    t.hint.paint(&failed.error)
                )?;
            }
        }
    }

    if !failed_branches.is_empty() {
        let attempted = failed_branches.len() + pushed_results.len();
        anyhow::bail!(
            "failed to push {} of {} branch{}",
            failed_branches.len(),
            attempted,
            if attempted == 1 { "" } else { "es" }
        );
    }

    Ok(())
}

fn handle_no_branch_specified(
    ctx: &Context,
    out: &mut OutputChannel,
) -> anyhow::Result<BranchSelection> {
    let t = theme::get();

    // Check if we're in an interactive terminal with human output format.
    // This comes first: push_all_branches computes its own candidates, so

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Read the per-branch failure lines printed above the summary — they carry the real cause per branch.
  2. If force-push protection refused to overwrite upstream commits and overwriting is intended, re-run with `-s/--skip-force-push-protection`.
  3. Fix credentials or connectivity and re-run; already-pushed branches are skipped (up-to-date is not an error).
  4. Preview first with `-d/--dry-run` to see which branches would be pushed and which require force.

Example fix

# before
but push               # one lane's remote moved -> failed to push 1 of 3 branches

# after
but push -d            # preview: see force/protection situation per branch
but push -s            # intentionally overwrite the stale remote ref
Defensive patterns

Strategy: retry

Validate before calling

# Preview before pushing: shows force requirements and upstream commits to be overwritten
but push -d

Try / catch

# Classify the per-branch error printed above the summary, then act
if ! but push 2>err.txt; then
  grep -q 'would be overwritten' err.txt && but push -s   # intentional overwrite only
  # auth/network errors: fix the cause, re-run `but push` (up-to-date branches are skipped)
fi

Prevention

When it happens

Trigger: Any per-branch failure during a multi-branch push (`but push` with no branch pushes all candidates): expired credentials, network/remote unreachable, pre-receive rejection, or force-push protection refusing to overwrite upstream commits that would be lost (note `-f` force is on by default, so protection is what usually blocks stale remotes).

Common situations: Stack pushes where one lane's remote moved because someone else pushed; tokens/SSH auth expiring mid-run; VPN/remote connectivity issues; pre-receive hooks rejecting a branch.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/69257c324d0ab0d8. Report an issue: GitHub.