gitbutlerapp/gitbutler · warning
Refusing to delete last named segment '{}' as it would leave
Error message
Refusing to delete last named segment '{}' as it would leave an anonymous segment What it means
remove_reference refuses to delete the last named segment of a stack that owns commits, because doing so would leave those commits in an anonymous segment with no ref — invisible/unattributable in the workspace UI. The guard fires only when the stack has commits and fewer than two named segments remain after the deletion.
Source
Thrown at crates/but-workspace/src/branch/remove_reference.rs:56
let Some((stack, _segment)) = workspace.find_segment_and_stack_by_refname(ref_name) else {
return Ok(None);
};
if avoid_anonymous_stacks
&& (stack
.segments
.iter()
.map(|s| s.commits.len())
.sum::<usize>()
> 0
&& stack
.segments
.iter()
.filter(|s| s.ref_info.is_some())
.count()
< 2)
{
bail!(
"Refusing to delete last named segment '{}' as it would leave an anonymous segment",
ref_name.shorten()
);
}
let deleted_ref = if let Some(r) = repo.try_find_reference(ref_name)? {
let safe = but_core::branch::SafeDelete::new(repo)?;
let out = safe.delete_reference(&r)?;
if let Some(paths) = out.checked_out_in_worktree_dirs {
bail_precondition!(
"Refusing to delete a branch that is checked out. Worktrees are: {paths:?}"
);
}
true
} else {
false
};
View on GitHub (pinned to caf1f223d3)
Solutions
- Use the workspace unapply operation instead — it moves commits and disposes of the workspace representation correctly.
- Move the commits to another branch (or integrate them) first, then delete the now-empty ref.
- Delete a different, non-last named segment if the goal is just pruning.
Defensive patterns
Strategy: validation
Validate before calling
let named_segments = stack.segments.iter().filter(|s| s.ref_info.is_some()).count();
let total_commits: usize = stack.segments.iter().map(|s| s.commits.len()).sum();
if total_commits > 0 && named_segments < 2 {
// deleting the last named segment would orphan its commits: use unapply instead
return route_to_unapply(ref_name);
} Try / catch
match remove_reference(repo, meta, ref_name, &stack) {
Err(err) if err.to_string().contains("last named segment") => {
unapply(repo, meta, &ws, ref_name, Options::default())
}
other => other,
} Prevention
- Route 'delete last branch of a stack' actions to unapply, not raw ref deletion.
- Check named-segment count and commit totals before deleting refs programmatically.
- Teach users that branches with commits must be unapplied, not deleted.
When it happens
Trigger: Calling remove_reference on the only ref-bearing segment of a stack whose segments total more than zero commits (e.g. deleting the sole branch of a stack that has work on it).
Common situations: Trying to delete the last branch of a workspace stack directly via git ref deletion instead of unapply; cleanup scripts iterating over refs hitting a stack's only named branch.
Related errors
- When using OpenRouter, you must provide a valid API key
- HTTP Error ${response.statusText}: ${text}
- Tearing off a branch requires a workspace common base
- Cannot unapply a branch from an ad-hoc detached workspace
- Expected to be in open workspace mode
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/858c9f228e4b9feb.
Report an issue: GitHub.