gitbutlerapp/gitbutler · error · anyhow::Error

Tearing off a branch requires a workspace common base

Error message

Tearing off a branch requires a workspace common base

What it means

Thrown by the tear-off path of move_branch in a managed workspace when the workspace has no lower-bound segment carrying a ref name. The lower bound ref (the workspace's common base/target branch) is what the torn-off branch gets re-parented onto, so without it the disconnect operation has no anchor target to select in the graph. It signals a workspace whose base stack is anonymous or missing rather than a bad API call.

Source

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

                ws_meta,
                new_tip: None,
                branch_stack_order: None,
            });
        }

        let Some(workspace_head) = workspace.tip_commit().map(|commit| commit.id) else {
            bail!("Couldn't find workspace head.")
        };
        let head_selector = editor
            .select_commit(workspace_head)
            .context("Failed to find the workspace head in the graph.")?;

        let Some(lower_bound_ref) = workspace
            .lower_bound_segment_id
            .map(|segment_id| &workspace.graph[segment_id])
            .and_then(|segment| segment.ref_name())
        else {
            bail!("Tearing off a branch requires a workspace common base");
        };

        let target_selector = editor
            .select_reference(lower_bound_ref)
            .context("Failed to find target reference in graph.")?;

        let DisconnectParameters {
            delimiter: subject_delimiter,
            children_to_disconnect,
            parents_to_disconnect,
        } = get_disconnect_parameters(
            &editor,
            source_stack,
            subject_segment,
            Some(workspace_head),
        )?;

        editor.disconnect_segment_from(

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Set (or restore) a target/base branch for the workspace in GitButler settings and re-sync, so the workspace has a named lower bound segment.
  2. Verify workspace.lower_bound_segment_id maps to a segment whose ref_name() is Some(...) before invoking the tear-off move.
  3. If the base ref was deleted, recreate it (e.g. from the remote tracking ref) and re-traverse the workspace.

Example fix

// before
let outcome = but_workspace::branch::move_branch(editor, &subject, &target)?;

// after
let ws = successful_rebase.overlayed_graph()?.into_workspace()?;
ensure!(
    ws.lower_bound_segment_id
        .and_then(|id| ws.graph[id].ref_name())
        .is_some(),
    "workspace has no common base ref; set a target branch first"
);
let outcome = but_workspace::branch::move_branch(editor, &subject, &target)?;
Defensive patterns

Strategy: validation

Validate before calling

let ws = successful_rebase.overlayed_graph()?.into_workspace()?;
let has_base_ref = ws
    .lower_bound_segment_id
    .map(|id| &ws.graph[id])
    .and_then(|segment| segment.ref_name())
    .is_some();
if !has_base_ref {
    // set a target branch for the workspace before tearing off
    return Ok(None);
}

Try / catch

match move_branch(editor, &subject, &target) {
    Ok(outcome) => { /* ... */ }
    Err(err) if err.to_string().contains("workspace common base") => {
        // prompt user to pick a target branch for the workspace
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Calling move_branch's tear-off flow when workspace.lower_bound_segment_id is None, or when the segment at that index has no ref_name() (an anonymous base segment). This happens for workspaces built on detached-HEAD bases or local-only commits with no target branch ref.

Common situations: Workspace created while HEAD was detached or on commits with no base branch; workspace whose target ref was deleted or never synced; repositories where the user never picked a target branch in GitButler settings.

Related errors


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