{"record":{"id":"6346b694659912b9","repo":"gitbutlerapp/gitbutler","slug":"cannot-unapply-branch-branch-from-an-ad-hoc-wo","errorCode":null,"errorMessage":"Cannot unapply branch '{branch}' from an ad-hoc workspace because the workspace cannot be empty","messagePattern":"Cannot unapply branch '(.+?)' from an ad-hoc workspace because the workspace cannot be empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/branch/unapply.rs","lineNumber":217,"sourceCode":"        let branch_commit_id = branch_ref\n            .as_mut()\n            .map(|reference| reference.peel_to_id().map(|id| id.detach()))\n            .transpose()?;\n\n        if ws.has_workspace_commit_in_ancestry(repo) {\n            bail!(\"Refusing to work on workspace whose workspace commit isn't at the top\");\n        }\n\n        let workspace_ref_name = ws.ref_name().map(ToOwned::to_owned);\n        if matches!(ws.kind, but_graph::workspace::WorkspaceKind::AdHoc)\n            && branch_ref\n                .as_ref()\n                .zip(workspace_ref_name.as_ref())\n                .is_some_and(|(to_unapply, workspace_ref_name)| {\n                    to_unapply.name() == workspace_ref_name.as_ref()\n                })\n        {\n            bail!(\n                \"Cannot unapply branch '{branch}' from an ad-hoc workspace because the workspace cannot be empty\",\n                branch = branch.shorten()\n            );\n        }\n\n        if let Some(workspace_ref_name) = workspace_ref_name.as_ref()\n            && workspace_ref_name.as_ref() == branch\n        {\n            return unapply_workspace_reference(\n                ws,\n                repo,\n                meta,\n                workspace_ref_name.as_ref(),\n                workspace_disposition,\n            );\n        }\n\n        let branch_in_ws = ws.find_segment_and_stack_by_refname(branch);","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-workspace/src/branch/unapply.rs#L199-L235","documentation":"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.","triggerScenarios":"Calling unapply(branch) in an ad-hoc workspace where branch == ws.ref_name() — i.e., trying to unapply the checked-out entrypoint branch itself.","commonSituations":"UI 'remove' button wired to unapply on the workspace's own branch; scripts that iterate all applied branches including the entrypoint one.","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."],"exampleFix":"// before\nfor branch in applied_branches { unapply(repo, meta, &ws, branch, opts)?; }\n\n// after\nfor branch in applied_branches {\n    if ws.ref_name().is_some_and(|ws_ref| ws_ref == branch) { continue; }\n    unapply(repo, meta, &ws, branch, opts)?;\n}","handlingStrategy":"validation","validationCode":"if matches!(ws.kind, but_graph::workspace::WorkspaceKind::AdHoc)\n    && ws.ref_name().is_some_and(|ws_ref| ws_ref == branch)\n{\n    // the workspace's own branch cannot be unapplied in ad-hoc mode\n    return show_notice(\"unapply a different branch or dissolve the workspace\");\n}","typeGuard":"fn is_workspace_entrypoint_branch(ws: &but_graph::Workspace, branch: &FullNameRef) -> bool {\n    matches!(ws.kind, but_graph::workspace::WorkspaceKind::AdHoc)\n        && ws.ref_name().is_some_and(|r| r == branch)\n}","tryCatchPattern":"match unapply(repo, meta, &ws, branch, opts) {\n    Err(err) if err.to_string().contains(\"workspace cannot be empty\") => {\n        ui::info(\"Switch away from the workspace to remove it\");\n        Ok(default_outcome())\n    }\n    other => other,\n}","preventionTips":["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()."],"tags":["gitbutler","unapply","ad-hoc-workspace","rust"],"backgroundTag":"cannot-empty-workspace","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}