gitbutlerapp/gitbutler · error
Cannot apply non-existing branch
Error message
Cannot apply non-existing branch '{branch}' What it means
`Workspace::apply` cannot apply a branch that does not exist as a reference. If no branch ref was resolved and the incoming branch is not a remote-tracking branch without a local tracking branch (a case that can be materialized), the library bails. This prevents creating phantom stacks from a typo or deleted branch.
Solutions
- Verify the branch exists: `git rev-parse --verify refs/heads/<name>` before applying
- Fetch the remote if the branch only exists remotely (`git fetch origin <name>`) so a local tracking branch can be created
- Correct the branch name in the calling code/script
Example fix
// before
ws.apply(meta, "feautre-x", ...)?;
// after
if repo.find_reference(&format!("refs/heads/feautre-x")).is_err() {
eprintln!("branch feautre-x does not exist locally");
return;
}
ws.apply(meta, "feature-x", ...)?; Defensive patterns
Strategy: validation
Validate before calling
if repo.try_find_reference(&format!("refs/heads/{name}")).is_err()
&& repo.try_find_reference(&format!("refs/remotes/*/{name}")).is_err() {
return Err(format!("branch {name} does not exist locally or remotely"));
} Type guard
fn branch_exists(repo: &gix::Repository, name: &str) -> bool {
repo.try_find_reference(format!("refs/heads/{name}")).map(|r| r.is_ok()).unwrap_or(false)
} Try / catch
match apply(...) {
Err(e) if e.to_string().contains("Cannot apply non-existing branch") => /* fetch or correct name */,
Err(e) => return Err(e.into()),
Ok(r) => r,
} Prevention
- Verify the branch ref exists before calling apply
- Fetch remotes so remote-only branches can be materialized
- Avoid hardcoding branch names in scripts; list refs first
When it happens
Trigger: Calling apply with a branch name that is neither a local ref nor derivable from remote-tracking refs — e.g. the branch was deleted, was never fetched, or the name is misspelled.
Common situations: Typo in branch name in a script; branch deleted on the remote and locally pruned; stale automation referencing renamed branches; applying before `git fetch` brought the remote branch in.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Branch ' ' not found
- Branch ' ' not found when checking for conflicts
- Cannot unapply non-existing branch
- failed to find branch
- Local branch ' ' not found
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/9823974422f8e6bc.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-workspace/src/branch/apply.rs:582
set_head_to_reference(
repo,
new_head_id,
// Point HEAD at the workspace ref whenever it isn't already there (covers creating the
// ref and switching off a directly-checked-out branch).
(!head_on_workspace_ref).then_some(workspace_ref_name_to_update.as_ref()),
)?;
return Ok(Outcome {
workspace: graph.into_workspace()?,
status: OutcomeStatus::Applied,
workspace_ref_created: needs_ws_ref_creation,
workspace_merge: None,
conflicting_stacks: Vec::new(),
applied_branches,
});
}
// We will want to merge, but be sure the branch exists, can't apply non-existing.
if branch_ref.is_none() && !incoming_branch_is_remote_tracking_without_local_tracking {
bail!(
"Cannot apply non-existing branch '{branch}'",
branch = branch.shorten()
);
}
let existing_stacks_superseded_by_branch =
find_superseded_stacks(branch.as_ref(), &ws, &mut ws_md);
// At this point, the workspace-metadata already knows the new branch(es), but the workspace itself
// doesn't see one or more of to-be-applied branches (to become stacks).
// These are, however, part of the graph by now, and we want to try to create a workspace
// merge.
let mut in_memory_repo = repo.clone().for_tree_diffing()?.with_object_memory();
let mut merge_result = WorkspaceCommit::from_new_merge_with_metadata(
filter_superseded_metadata_stacks(
ws_md.stacks.iter(),
&existing_stacks_superseded_by_branch,
),
filter_superseded_anon_stacks(View on GitHub (pinned to 58e5313667)