gitbutlerapp/gitbutler · error

Cannot add the target

Error message

Cannot add the target '{branch}' branch to its own workspace

What it means

`but_workspace::branch::apply` refuses to apply a branch into a workspace when that branch already is the workspace's target branch (or its local tracking branch). Doing so would make a stack its own base, which is an invalid workspace state, so it bails early after `try_find_validated_ref`.

Solutions

  1. Check before calling: skip apply when `ws.is_branch_the_target_or_its_local_tracking_branch(branch)` is true.
  2. Pass the branch you actually intend to integrate instead of the workspace target branch.
  3. If the branch is already the target, no apply is needed — treat it as a no-op in the caller.

Example fix

// before
ws.branch_apply(repo, &branch, meta, None, workspace, opts).await?;
// after
if !ws.is_branch_the_target_or_its_local_tracking_branch(&branch) {
    ws.branch_apply(repo, &branch, meta, None, workspace, opts).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

if ws.is_branch_the_target_or_its_local_tracking_branch(&branch) {
    return Ok(()); // nothing to do: branch already is the target
}
ws.branch_apply(repo, &branch, meta, None, workspace, opts).await?;

Try / catch

// Rust
if let Err(e) = ws.branch_apply(repo, &branch, ...).await {
    if e.to_string().starts_with("Cannot add the target") { return Ok(()); }
    return Err(e);
}

Prevention

When it happens

Trigger: Calling `apply(...)` with `branch` equal to the workspace's target branch name or its local tracking branch, detected via `ws.is_branch_the_target_or_its_local_tracking_branch(branch)`.

Common situations: UI/CLI automation that always calls apply on the 'current' branch after a checkout; scripting that iterates all branches including the target; passing an already-applied branch back into apply.

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


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/62cda527e245cf6d. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-workspace/src/branch/apply.rs:251

    workspace: but_graph::Workspace,
    repo: &gix::Repository,
    meta: &mut impl RefMetadata,
    Options {
        workspace_merge: integration_mode,
        on_workspace_conflict,
        workspace_reference_naming,
        order,
        new_stack_id,
        allow_applying_already_applied_branch_when_outside_workspace,
    }: Options,
) -> anyhow::Result<Outcome> {
    let ws = workspace;
    let new_stack_id = new_stack_id.unwrap_or(generate_new_stack_id);
    let branch_orig = branch;
    let (mut branch_ref, mut incoming_branch_is_remote_tracking_without_local_tracking) =
        (try_find_validated_ref(repo, branch, "apply")?, false);
    if ws.is_branch_the_target_or_its_local_tracking_branch(branch) {
        bail!("Cannot add the target '{branch}' branch to its own workspace");
    }
    let mut branch = branch.to_owned();
    if branch
        .category()
        .is_some_and(|c| c == Category::RemoteBranch)
    {
        // TODO(gix): we really want to have a function to return the local tracking branch
        //            fix this in other places, too.
        let Some((upstream_branch_name, _remote_name)) =
            repo.upstream_branch_and_remote_for_tracking_branch(branch.as_ref())?
        else {
            // TODO: actually create a local trakcing branch with proper configuration.
            bail!("Couldn't find remote refspecs that would match {branch}");
        };
        // Pretend the upstream branch is also the local tracking name.
        incoming_branch_is_remote_tracking_without_local_tracking = true;
        branch = upstream_branch_name;
        branch_ref = try_find_validated_ref(repo, branch.as_ref(), "apply")?;

View on GitHub (pinned to 58e5313667)