gitbutlerapp/gitbutler · error
Cannot unapply workspace reference '{}' without switching aw
Error message
Cannot unapply workspace reference '{}' without switching away from it What it means
unapply_workspace_reference must check out another ref to move HEAD away from the workspace ref it is removing, but the passed WorkspaceDisposition does not allow switching away. Only the PreventUnnecessaryWorkspaceReferences variants set may_switch_away_from_workspace() to true; the default KeepWorkspaceCommit (and KeepWorkspaceReference) forbid it. Pass a disposition that permits switching when you actually want the workspace ref gone.
Source
Thrown at crates/but-workspace/src/branch/unapply.rs:554
/// Unapply the managed workspace reference itself.
///
/// - Run before normal branch removal because the workspace ref is a container, not a stack segment.
/// - Reject dispositions that keep the workspace ref because unapplying it requires switching away.
/// - Pick a named checkout target from the current projection.
/// - Reject GitButler-conflicted target commits with a ref-aware error.
/// - Safely checkout the target commit, then switch `HEAD` to the target ref.
/// - Optionally delete the managed workspace ref and metadata.
/// - Retraverse from the target ref so the returned workspace matches the new `HEAD`.
fn unapply_workspace_reference(
ws: &but_graph::Workspace,
repo: &gix::Repository,
meta: &mut impl RefMetadata,
workspace_ref_name: &FullNameRef,
disposition: WorkspaceDisposition,
) -> anyhow::Result<Outcome<'static>> {
if !disposition.may_switch_away_from_workspace() {
bail!(
"Cannot unapply workspace reference '{}' without switching away from it",
workspace_ref_name.shorten()
);
}
let ref_to_checkout = ref_to_checkout_after_workspace_unapply(ws)?;
safe_checkout_ref_to_checkout(
repo,
&ref_to_checkout,
but_core::worktree::checkout::Options {
skip_head_update: true,
..Default::default()
},
)?;
let workspace_ref_expected = ws
.tip_commit()
.context("BUG: unborn should be impossible here")?View on GitHub (pinned to caf1f223d3)
Solutions
- Pass WorkspaceDisposition::PreventUnnecessaryWorkspaceReferences (or ...KeepWorkspaceCommit) so unapply may switch HEAD away and delete the workspace ref.
- If you must keep the workspace ref checked out, do not unapply the workspace reference itself — unapply inner branches instead.
- Check disposition.may_switch_away_from_workspace() semantics before wiring UI actions.
Example fix
// before
let opts = Options::default(); // KeepWorkspaceCommit
unapply(repo, meta, &ws, ws_ref, opts)?;
// after
let opts = Options {
workspace_disposition: WorkspaceDisposition::PreventUnnecessaryWorkspaceReferences,
};
unapply(repo, meta, &ws, ws_ref, opts)?; Defensive patterns
Strategy: validation
Validate before calling
use but_workspace::branch::unapply::WorkspaceDisposition;
let disposition = WorkspaceDisposition::PreventUnnecessaryWorkspaceReferences;
if !matches!(disposition, WorkspaceDisposition::KeepWorkspaceCommit | WorkspaceDisposition::KeepWorkspaceReference) {
// disposition may switch away from the workspace ref: safe to unapply it
} Try / catch
match unapply(repo, meta, &ws, ws_ref, opts) {
Err(err) if err.to_string().contains("without switching away from it") => {
let opts = Options {
workspace_disposition: WorkspaceDisposition::PreventUnnecessaryWorkspaceReferences,
};
unapply(repo, meta, &ws, ws_ref, opts)
}
other => other,
} Prevention
- Never use Options::default() when unapplying the workspace reference itself.
- Pick the disposition based on intent: keep the ref vs dissolve the workspace.
- Document the PreventUnnecessaryWorkspaceReferences variants in wrapper layers.
When it happens
Trigger: Calling unapply on the workspace's own reference with Options { workspace_disposition: KeepWorkspaceCommit } or KeepWorkspaceReference — dispositions that require staying on the workspace ref.
Common situations: Default-constructed Options (KeepWorkspaceCommit is the #[default]) used on the workspace-reference unapply path; callers copying branch-unapply options into workspace-ref unapply.
Related errors
- Cannot unapply workspace reference by checking out conflicte
- Refusing to work on workspace whose workspace commit isn't a
- Cannot unapply branch '{branch}' from an ad-hoc workspace be
- Cannot unapply non-existing branch '{branch}'
- Cannot unapply a branch from an ad-hoc detached workspace
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/1e2d712d74a379f6.
Report an issue: GitHub.