gitbutlerapp/gitbutler · error
Branch {branch_name} not found
Error message
Branch {branch_name} not found What it means
branch_land resolves refs/heads/<branch_name> in the local repository via gix try_find_reference; if no such local branch exists it bails with this message before fetching or mutating anything. It looks for a real local ref — remote-only names, virtual names, and typos all fail here.
Source
Thrown at crates/but-api/src/land/merge.rs:39
Merge {
oid: gix::ObjectId,
target_oid: gix::ObjectId,
},
}
/// Decide how to land `branch_name` onto the target and, for the merge case, build a signed,
/// rename-aware merge commit. Conflicts bail here, before anything is pushed or moved.
pub(super) fn decide_land_outcome(
repo: &gix::Repository,
branch_name: &str,
fetch_remote_name: &str,
target_branch_name: &str,
no_ff: bool,
) -> anyhow::Result<LandOutcome> {
let feature_ref_name = format!("refs/heads/{branch_name}");
let feature_oid = repo
.try_find_reference(&feature_ref_name)?
.ok_or_else(|| anyhow::anyhow!("Branch {branch_name} not found"))?
.into_fully_peeled_id()?
.detach();
let target_ref_name = format!("refs/remotes/{fetch_remote_name}/{target_branch_name}");
let target_oid = repo
.try_find_reference(&target_ref_name)?
.ok_or_else(|| anyhow::anyhow!("Target branch {target_ref_name} not found"))?
.into_fully_peeled_id()?
.detach();
// No common ancestor: refuse rather than merge two unrelated histories onto the target.
let Some(merge_base) = super::merge_base_opt(repo, feature_oid, target_oid)? else {
bail!(
"Cannot land {branch_name}: it shares no history with {fetch_remote_name}/{target_branch_name}"
);
};
if merge_base == feature_oid {View on GitHub (pinned to 2497b8007a)
Solutions
- List candidates first: git branch --list (or the workspace stack listing) and land the exact local branch name.
- If the branch exists only on the remote, materialize the local ref first: git fetch <remote> && git branch <name> <remote>/<name>.
- Strip remote prefixes — pass the short name, not origin/<name>.
Example fix
git branch --list 'feat/*' git branch feat/auth origin/feat/auth # only if the local ref is missing but land feat/auth
Defensive patterns
Strategy: validation
Validate before calling
fn local_branch_exists(repo: &gix::Repository, branch: &str) -> anyhow::Result<bool> {
Ok(repo.try_find_reference(&format!("refs/heads/{branch}"))?.is_some())
} Prevention
- Resolve names with git rev-parse --verify refs/heads/<name> (or try_find_reference) before land.
- Offer only local stack branch names in UI pickers.
- Strip remote prefixes from user-supplied names.
When it happens
Trigger: `but land <name>` (branch_land -> decide_land_outcome) where refs/heads/<name> does not exist: typo, name written as origin/<name>, branch that exists only on the remote, or a local branch deleted/pruned earlier.
Common situations: Tab-completing remote branch names; landing after branch cleanup pruned the local ref; case-sensitivity mistakes; scripts forwarding reflogs or remote names.
Related errors
- Target branch {target_ref_name} not found
- HTTP Error ${response.statusText}: ${text}
- No HEAD reference found for remote {remote_name}
- No commits were provided to squash
- no commit IDs provided for uncommit
AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17).
Data as JSON: /api/errors/ec544f17a5f7f468.
Report an issue: GitHub.