gitbutlerapp/gitbutler · error
Cannot unapply non-existing branch '{branch}'
Error message
Cannot unapply non-existing branch '{branch}' What it means
unapply looks the branch up both in git (try_find_validated_ref) and in the workspace projection (find_segment_and_stack_by_refname). This error fires when both miss: the branch neither exists as a git reference nor as a segment in the workspace, so there is nothing to unapply and the name is simply wrong or stale.
Source
Thrown at crates/but-workspace/src/branch/unapply.rs:238
);
}
if let Some(workspace_ref_name) = workspace_ref_name.as_ref()
&& workspace_ref_name.as_ref() == branch
{
return unapply_workspace_reference(
ws,
repo,
meta,
workspace_ref_name.as_ref(),
workspace_disposition,
);
}
let branch_in_ws = ws.find_segment_and_stack_by_refname(branch);
if branch_in_ws.is_none() {
if branch_ref.is_none() {
bail!(
"Cannot unapply non-existing branch '{branch}'",
branch = branch.shorten()
);
}
// The branch exists in Git, but does not in the workspace: Nothing to do.
return Ok(Outcome::new(Cow::Borrowed(workspace)));
}
let branch_stack_was_entrypoint = branch_in_ws
.is_some_and(|(stack, _)| stack.segments.iter().any(|segment| segment.is_entrypoint));
let workspace_tip_was_entrypoint = ws.is_entrypoint();
let Some(workspace_ref_name) = workspace_ref_name else {
// This is an ad-hoc workspace by merit of being unnamed.
bail!("Cannot unapply a branch from an ad-hoc detached workspace");
};
let mut ws_md = meta.workspace(workspace_ref_name.as_ref())?;
if ws.kind.has_managed_ref() || ws.has_metadata() {
ws.reconcile_metadata(&mut ws_md)?;View on GitHub (pinned to caf1f223d3)
Solutions
- Refresh the branch list (re-traverse workspace + repo refs) and only offer branches that still exist.
- Treat this case as a no-op in idempotent callers instead of surfacing an error.
- Verify the exact spelling and full ref name (refs/heads/...) before calling.
Example fix
// before
unapply(repo, meta, &ws, branch, opts)?;
// after
if repo.try_find_reference(branch)?.is_none()
&& ws.find_segment_and_stack_by_refname(branch).is_none()
{
return Ok(Outcome::new(Cow::Borrowed(&ws))); // nothing to unapply
}
unapply(repo, meta, &ws, branch, opts)?; Defensive patterns
Strategy: validation
Validate before calling
if repo.try_find_reference(branch)?.is_none()
&& ws.find_segment_and_stack_by_refname(branch).is_none()
{
// nothing to unapply: treat as idempotent no-op
return Ok(Outcome::new(Cow::Borrowed(&ws)));
} Type guard
fn branch_exists_anywhere(ws: &but_graph::Workspace, repo: &gix::Repository, branch: &FullNameRef) -> bool {
repo.try_find_reference(branch).ok().flatten().is_some()
|| ws.find_segment_and_stack_by_refname(branch).is_some()
} Try / catch
match unapply(repo, meta, &ws, branch, opts) {
Err(err) if err.to_string().contains("non-existing branch") => {
Ok(Outcome::new(Cow::Borrowed(&ws))) // idempotent no-op
}
other => other,
} Prevention
- Refresh branch lists before offering unapply actions.
- Make batch unapply idempotent: treat missing branches as done.
- Validate exact full ref names from user input.
When it happens
Trigger: Calling unapply with a branch name that has no git ref and no workspace segment — typo, already-deleted branch, or a name that was never applied.
Common situations: Stale UI state after another client deleted the branch; scripts replaying an old branch list; short-name/full-name mismatches.
Related errors
- Couldn't find target branch to move in workspace with refere
- Refusing to work on workspace whose workspace commit isn't a
- Cannot unapply branch '{branch}' from an ad-hoc workspace be
- Cannot unapply a branch from an ad-hoc detached workspace
- Cannot unapply branch '{branch}' from an ad-hoc workspace be
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/4c2850a4f6adb6bb.
Report an issue: GitHub.