gitbutlerapp/gitbutler · error · anyhow::Error

Couldn't find branch to move in workspace with reference nam

Error message

Couldn't find branch to move in workspace with reference name: {subject_branch_name}

What it means

`tear_off_branch` (move_branch.rs) bails when `workspace.find_segment_and_stack_by_refname(subject_branch_name)` finds no stack segment for the given reference name — the branch to move is not part of the current GitButler workspace graph. The lookup happens on the overlayed workspace after `editor.rebase()`, so the name must match a segment ref exactly.

Source

Thrown at crates/but-workspace/src/branch/move_branch.rs:67

    /// `workspace` - Used for getting the surrounding context of the branch being torn off.
    ///     In the future, we should not rely on the projection and do it fully on the graph.
    ///
    /// `subject_branch_name` - The branch to take out of a stack.
    ///
    /// `stack_id_override` - Optionally, the ID to use for the newly created stack.
    ///     Mainly used for testing purposes.
    ///
    /// Returns the in memory update [outcome](Outcome) that can then used for materialisation.
    pub fn tear_off_branch<'ws, 'meta, M: RefMetadata>(
        editor: Editor<'ws, 'meta, M>,
        subject_branch_name: &FullNameRef,
        stack_id_override: Option<StackId>,
    ) -> anyhow::Result<Outcome<'ws, 'meta, M>> {
        let successful_rebase = editor.rebase()?;
        let workspace = successful_rebase.overlayed_graph()?.into_workspace()?;
        let mut editor = successful_rebase.into_editor();
        let Some(source) = workspace.find_segment_and_stack_by_refname(subject_branch_name) else {
            bail!(
                "Couldn't find branch to move in workspace with reference name: {subject_branch_name}"
            );
        };

        // We're currently stopping the move branch operations imperatively at this stage, in order to
        // reduce the scope of this first iteration of moving the branches.
        // TODO: Enable and test that we can move branches in any kind of workspace.
        match &workspace.kind {
            WorkspaceKind::Managed { .. } => {}
            WorkspaceKind::ManagedMissingWorkspaceCommit { .. } => {
                bail!("Moving branches currently need a workspace commit")
            }
            WorkspaceKind::AdHoc => {
                bail!("Moving branches in non-managed workspaces is not supported");
            }
        };

        let mut ws_meta = workspace.metadata.clone();

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Verify the branch is a workspace stack segment first: `workspace.find_segment_and_stack_by_refname(name).is_some()`; if not, refresh/rebuild the workspace graph before retrying.
  2. Pass the full reference name (`refs/heads/...`) exactly as segments store it — check `segment.ref_name()`.
  3. If the branch lives outside the workspace, add it to the workspace (apply/adopt) before moving.
  4. If it was deleted concurrently, re-sync the UI list from the current workspace and drop the stale request.
Defensive patterns

Strategy: validation

Validate before calling

// Must resolve to a workspace segment before moving:
let workspace = /* current but_graph::Workspace */;
if workspace.find_segment_and_stack_by_refname(subject_branch_name).is_none() {
    anyhow::bail!("branch {subject_branch_name} is not a stack segment in this workspace; refresh the workspace graph or add the branch first");
}

Type guard

fn branch_is_moveable(ws: &but_graph::Workspace, name: &gix::refs::FullNameRef) -> bool {
    ws.find_segment_and_stack_by_refname(name).is_some() && matches!(ws.kind, but_graph::WorkspaceKind::Managed { .. })
}

Try / catch

if let Err(err) = move_branch::tear_off_branch(editor, &subject_branch_name, stack_override) {
    if err.to_string().contains("Couldn't find branch to move") {
        // refresh workspace graph and re-check the branch list; likely stale or unmanaged branch
    }
}

Prevention

When it happens

Trigger: Calling the move-branch API with a ref name that is not a segment in the workspace: an unmanaged local branch, a remote tracking ref, a typo'd/partial name, or a branch that was deleted/renamed between the UI listing and the call. Also stale workspace data (graph built before the branch was added).

Common situations: Trying to move a branch that was never adopted into the workspace; racing with a concurrent branch deletion/rename; passing `refs/heads/x` vs `x` inconsistently; workspace cache out of date after external git operations.

Related errors


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