{"record":{"id":"75d0adb1a26c69f1","repo":"gitbutlerapp/gitbutler","slug":"branch-not-found-available-branches","errorCode":null,"errorMessage":"Branch '{}' not found. Available branches:\n{}","messagePattern":"Branch '(.+?)' not found\\. Available branches:\n(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/push.rs","lineNumber":1110,"sourceCode":"        flags.push(but_gerrit::PushFlag::Private);\n    }\n\n    Ok(flags)\n}\n\nfn resolve_branch_name(\n    ctx: &mut Context,\n    id_map: &IdMap,\n    branch_id: &str,\n) -> anyhow::Result<String> {\n    // Try to resolve as CliId first\n    let cli_ids = id_map.parse_using_context(branch_id, ctx)?;\n\n    if cli_ids.is_empty() {\n        // If no CliId matches, treat as literal branch name but validate it exists\n        let available_branches = get_available_branch_names(ctx)?;\n        if !available_branches.contains(&branch_id.to_string()) {\n            return Err(anyhow::anyhow!(\n                \"Branch '{}' not found. Available branches:\\n{}\",\n                branch_id,\n                format_branch_suggestions(&available_branches)\n            ));\n        }\n        return Ok(branch_id.to_string());\n    }\n\n    if cli_ids.len() > 1 {\n        let branch_names: Vec<String> = cli_ids\n            .iter()\n            .filter_map(|id| match id {\n                CliId::Branch(branch) => Some(branch.name.clone()),\n                _ => None,\n            })\n            .collect();\n\n        if !branch_names.is_empty() {","sourceCodeStart":1092,"sourceCodeEnd":1128,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/legacy/push.rs#L1092-L1128","documentation":"`resolve_branch_name` first parses the argument against the workspace IdMap; when nothing matches it falls back to a literal branch name, but requires it to appear in `get_available_branch_names`, which enumerates branches of applied stacks. So the error means: not a known CLI id, and not a branch of any applied stack — a branch that exists only as a plain Git ref does not qualify.","triggerScenarios":"Running `but push <name>` with a typo, with a branch whose stack is currently unapplied, or with a regular Git branch that was never brought into the GitButler workspace.","commonSituations":"Autocomplete offering raw git branches instead of workspace branches; stack unapplied or archived before pushing; branch created outside the workspace with plain `git checkout -b`.","solutions":["Read the 'Available branches' list the error prints and copy the exact name","If the branch's stack is unapplied, apply it first so it becomes selectable","If it is a plain Git branch, push it with `git push` or bring it into the workspace","Check `but status` to see which stacks and branches are currently applied"],"exampleFix":"# before\nbut push feaure-x\n# error: Branch 'feaure-x' not found. Available branches: ...\n\n# after\nbut push feature-x   # exact name from the printed suggestion list","handlingStrategy":"validation","validationCode":"# Confirm the branch is in an applied stack before pushing\nbut status | grep -F \"$branch\" || echo \"branch '$branch' not in an applied stack\" >&2","typeGuard":null,"tryCatchPattern":"// Parse the suggestion list out of the failure to offer corrections\nlet out = Command::new(\"but\").args([\"push\", name]).output()?;\nlet err = String::from_utf8_lossy(&out.stderr).to_string();\nif err.contains(\"not found. Available branches:\") {\n    let list: Vec<&str> = err.lines().skip_while(|l| !l.contains(\"Available\")).skip(1).collect();\n    // present `list` to the user as candidates\n}","preventionTips":["Push workspace branches, not raw git refs — check `but status` first","Apply stacks before pushing their branches","Copy names from the error's suggestion list or command output, not from memory"],"tags":["push","branch-resolution","workspace","branch-not-found"],"backgroundTag":"branch-not-found","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}