{"record":{"id":"69257c324d0ab0d8","repo":"gitbutlerapp/gitbutler","slug":"failed-to-push-of-branch","errorCode":null,"errorMessage":"failed to push {} of {} branch{}","messagePattern":"failed to push (.+?) of (.+?) branch(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/push.rs","lineNumber":838,"sourceCode":"                    \"branch\"\n                } else {\n                    \"branches\"\n                }\n            )?;\n            for failed in &failed_branches {\n                writeln!(\n                    human,\n                    \"    {} - {}\",\n                    t.error.paint(&failed.branch_name),\n                    t.hint.paint(&failed.error)\n                )?;\n            }\n        }\n    }\n\n    if !failed_branches.is_empty() {\n        let attempted = failed_branches.len() + pushed_results.len();\n        anyhow::bail!(\n            \"failed to push {} of {} branch{}\",\n            failed_branches.len(),\n            attempted,\n            if attempted == 1 { \"\" } else { \"es\" }\n        );\n    }\n\n    Ok(())\n}\n\nfn handle_no_branch_specified(\n    ctx: &Context,\n    out: &mut OutputChannel,\n) -> anyhow::Result<BranchSelection> {\n    let t = theme::get();\n\n    // Check if we're in an interactive terminal with human output format.\n    // This comes first: push_all_branches computes its own candidates, so","sourceCodeStart":820,"sourceCodeEnd":856,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/legacy/push.rs#L820-L856","documentation":"`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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Read the per-branch failure lines printed above the summary — they carry the real cause per branch.","If force-push protection refused to overwrite upstream commits and overwriting is intended, re-run with `-s/--skip-force-push-protection`.","Fix credentials or connectivity and re-run; already-pushed branches are skipped (up-to-date is not an error).","Preview first with `-d/--dry-run` to see which branches would be pushed and which require force."],"exampleFix":"# before\nbut push               # one lane's remote moved -> failed to push 1 of 3 branches\n\n# after\nbut push -d            # preview: see force/protection situation per branch\nbut push -s            # intentionally overwrite the stale remote ref","handlingStrategy":"retry","validationCode":"# Preview before pushing: shows force requirements and upstream commits to be overwritten\nbut push -d","typeGuard":null,"tryCatchPattern":"# Classify the per-branch error printed above the summary, then act\nif ! but push 2>err.txt; then\n  grep -q 'would be overwritten' err.txt && but push -s   # intentional overwrite only\n  # auth/network errors: fix the cause, re-run `but push` (up-to-date branches are skipped)\nfi","preventionTips":["Run `but push -d` before real pushes to catch force/protection situations early.","Keep forge credentials fresh and check remote reachability first.","Expect partial-success semantics: succeeded branches are not re-pushed on retry; only failures are retried."],"tags":["cli","push","remote","force-push","gitbutler"],"backgroundTag":"git-push-rejected","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}