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

  1. Use the workspace unapply operation instead — it moves commits and disposes of the workspace representation correctly.
  2. Move the commits to another branch (or integrate them) first, then delete the now-empty ref.
  3. 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

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


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/858c9f228e4b9feb. Report an issue: GitHub.