gitbutlerapp/gitbutler · error
Refusing to apply a reference that already is a workspace
Error message
Refusing to apply a reference that already is a workspace: '{}' What it means
`Workspace::apply` refuses to apply a branch reference that is itself already a workspace root in the workspace metadata. A reference can only be either a workspace or an applied branch, not both, so applying it as a branch would corrupt the workspace structure. This is a deliberate precondition, not a transient failure.
Solutions
- Use the actual feature branch name, not the workspace branch, in the apply call
- If the branch should no longer be a workspace, remove its workspace registration in the metadata before applying
- Check `meta.workspace_opt(branch_ref)` before calling apply and skip or handle workspace references explicitly
Example fix
// before
ws.apply(meta, "my-workspace-branch", ...)?;
// after
if meta.workspace_opt(&branch)?.is_some() {
bail!("{ } is a workspace, pick a stack branch instead");
}
ws.apply(meta, "feature-branch", ...)?; Defensive patterns
Strategy: validation
Validate before calling
if meta.workspace_opt(&branch_ref)?.is_some() {
return Err(format!("{} is a workspace; apply a regular branch instead", branch_ref.shorten()));
} Type guard
fn is_workspace_branch(meta: &M, r: &gix::refs::Reference) -> bool {
meta.workspace_opt(r).map(|o| o.is_some()).unwrap_or(false)
} Try / catch
match apply(...) {
Err(e) if e.to_string().contains("already is a workspace") => /* pick a stack branch instead */,
Err(e) => return Err(e.into()),
Ok(r) => r,
} Prevention
- Resolve the branch to a stack branch, never the workspace branch itself
- Before scripting applies, filter out refs registered as workspaces
- Check workspace metadata listing before applying unfamiliar branch names
When it happens
Trigger: Calling `but_workspace::branch::apply` (or higher-level `but apply`) with a branch name that `meta.workspace_opt(branch)` reports as an existing workspace, while that workspace commit is not at the top of its ancestry (the prior check passed).
Common situations: Users pass the workspace/meta branch name instead of a feature branch; a branch previously used as a workspace is re-applied after the workspace commit was removed from the tip; scripted apply loops iterating over all refs including workspace branches.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Couldn't find workspace head.
- Expected to be in open workspace mode
- Ad-hoc (single-branch) branch moves are not supported…
- Branch ' ' cannot be created: the target commit ( ) already…
- BranchNotFound
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/a908ba4ebe3da9ea.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-workspace/src/branch/apply.rs:362
});
};
if let Some(ws_ref_name) = ws.ref_name()
&& repo.try_find_reference(ws_ref_name)?.is_none()
{
// The workspace is the probably ad-hoc, and doesn't exist, *assume* unborn.
bail!(
"Cannot create reference on unborn branch '{}'",
ws_ref_name.shorten()
);
}
if ws.has_workspace_commit_in_ancestry(repo) {
bail!("Refusing to work on workspace whose workspace commit isn't at the top");
}
if meta.workspace_opt(branch.as_ref())?.is_some() {
bail!(
"Refusing to apply a reference that already is a workspace: '{}'",
branch.shorten()
);
}
// In general, we only have to deal with one branch to apply. But when we are on an adhoc workspace,
// we need to assure both branches go into the existing or the new workspace:
// - the current one and the one to apply, if these are different.
// The returned workspace ref name will be set to the new merge commit, if created, or it may not change
// at all if the workspace can be created by just setting metadata.
let (workspace_ref_name_to_update, branches_to_apply) = match &ws.kind {
WorkspaceKind::Managed { ref_info }
| WorkspaceKind::ManagedMissingWorkspaceCommit { ref_info } => {
(ref_info.ref_name.clone(), vec![branch.clone()])
}
WorkspaceKind::AdHoc => {
// We need to switch over to a possibly existing workspace.
// We know that the current branch is *not* reachable from the workspace or isn't naturally included,
// so it needs to be added as well.View on GitHub (pinned to 58e5313667)