gitbutlerapp/gitbutler · error
Cannot unapply branch '{branch}' from an ad-hoc workspace be
Error message
Cannot unapply branch '{branch}' from an ad-hoc workspace because the workspace cannot be empty What it means
In an ad-hoc workspace, unapplying the very branch that the workspace ref points at (the entrypoint branch) would leave the workspace with nothing in it, which ad-hoc workspaces cannot represent. The guard compares the branch to unapply against the workspace's own ref name and refuses the identity case. Unapply any other branch, or dissolve the workspace via the workspace-reference path.
Source
Thrown at crates/but-workspace/src/branch/unapply.rs:217
let branch_commit_id = branch_ref
.as_mut()
.map(|reference| reference.peel_to_id().map(|id| id.detach()))
.transpose()?;
if ws.has_workspace_commit_in_ancestry(repo) {
bail!("Refusing to work on workspace whose workspace commit isn't at the top");
}
let workspace_ref_name = ws.ref_name().map(ToOwned::to_owned);
if matches!(ws.kind, but_graph::workspace::WorkspaceKind::AdHoc)
&& branch_ref
.as_ref()
.zip(workspace_ref_name.as_ref())
.is_some_and(|(to_unapply, workspace_ref_name)| {
to_unapply.name() == workspace_ref_name.as_ref()
})
{
bail!(
"Cannot unapply branch '{branch}' from an ad-hoc workspace because the workspace cannot be empty",
branch = branch.shorten()
);
}
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);View on GitHub (pinned to caf1f223d3)
Solutions
- Unapply a different branch; the entrypoint branch of an ad-hoc workspace cannot be removed by unapply.
- To empty the workspace, switch away from it / dissolve it through the workspace-unapply flow instead.
- Exclude the workspace ref name from any batch-unapply loops.
Example fix
// before
for branch in applied_branches { unapply(repo, meta, &ws, branch, opts)?; }
// after
for branch in applied_branches {
if ws.ref_name().is_some_and(|ws_ref| ws_ref == branch) { continue; }
unapply(repo, meta, &ws, branch, opts)?;
} Defensive patterns
Strategy: validation
Validate before calling
if matches!(ws.kind, but_graph::workspace::WorkspaceKind::AdHoc)
&& ws.ref_name().is_some_and(|ws_ref| ws_ref == branch)
{
// the workspace's own branch cannot be unapplied in ad-hoc mode
return show_notice("unapply a different branch or dissolve the workspace");
} Type guard
fn is_workspace_entrypoint_branch(ws: &but_graph::Workspace, branch: &FullNameRef) -> bool {
matches!(ws.kind, but_graph::workspace::WorkspaceKind::AdHoc)
&& ws.ref_name().is_some_and(|r| r == branch)
} Try / catch
match unapply(repo, meta, &ws, branch, opts) {
Err(err) if err.to_string().contains("workspace cannot be empty") => {
ui::info("Switch away from the workspace to remove it");
Ok(default_outcome())
}
other => other,
} Prevention
- Filter the workspace entrypoint branch out of unapply UI actions.
- Offer 'dissolve workspace' as the way to remove the last ad-hoc branch.
- In loops, skip branch == ws.ref_name().
When it happens
Trigger: Calling unapply(branch) in an ad-hoc workspace where branch == ws.ref_name() — i.e., trying to unapply the checked-out entrypoint branch itself.
Common situations: UI 'remove' button wired to unapply on the workspace's own branch; scripts that iterate all applied branches including the entrypoint one.
Related errors
- Refusing to work on workspace whose workspace commit isn't a
- Cannot unapply non-existing branch '{branch}'
- Cannot unapply a branch from an ad-hoc detached workspace
- Cannot unapply branch '{branch}' from an ad-hoc workspace be
- Cannot unapply workspace reference '{}' without switching aw
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/6346b694659912b9.
Report an issue: GitHub.