gitbutlerapp/gitbutler · error

BUG: failed to apply head ref

Error message

BUG: failed to apply head ref ({head_name}). Failed with {:?}

What it means

When creating a branch in single-branch mode, the operation applies the current head ref via an operation/outcome API. The outcome's status must report a persisted mutation; if it does not, the head ref could not be applied to the new branch and the code bails with a BUG-prefixed message including the head name and status — signaling an internal invariant violation rather than user error.

Solutions

  1. Retry the command — transient locks or concurrent edits often resolve on a second attempt
  2. Run `but status` / re-open the workspace to refresh stale state, then retry
  3. Check for and dismiss external git processes touching the repo, then retry
  4. If reproducible, report a bug with the head ref name and the status payload from the message

Example fix

// before
but branch new my-branch   # fails with BUG: failed to apply head ref
// after
git -C . status   # ensure repo is healthy / no concurrent process
but status && but branch new my-branch
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check workspace health before branch creation
await exec('but status'); // non-zero output/errors indicate stale or locked workspace state

Type guard

const isBugApplyFailure = (e) => e instanceof Error && /BUG: failed to apply head ref/.test(e.message);

Try / catch

try {
  await exec(`but branch new ${name}`);
} catch (e) {
  if (isBugApplyFailure(e)) {
    // refresh workspace state and retry once
    await exec('but status');
    await exec(`but branch new ${name}`);
  } else throw e;
}

Prevention

When it happens

Trigger: `but branch new <name>` in single-branch mode where the workspace operation that applies head_name returns an outcome whose status does not count as persisted_mutation() (e.g. a rejected/conflicted/failed apply), after the earlier operation call already returned Ok.

Common situations: Corrupted or locked workspace state; refs moved concurrently by another process (IDE, second CLI invocation); stack-engine edge cases after a rebase or external git mutation; genuine bug in the operation pipeline.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at crates/but/src/command/legacy/branch/new.rs:370

            // if the branch had no commits `set_base_branch` doesn't apply it
            //
            // this also has the effect of entering the workspace with one branch applied
            {
                let (repo, mut ws, _db) = ctx.workspace_mut_and_db_with_perm(perm)?;
                let outcome = but_workspace::branch::apply(
                    head_name.as_ref(),
                    ws.clone(),
                    &repo,
                    meta,
                    but_workspace::branch::apply::Options {
                        allow_applying_already_applied_branch_when_outside_workspace: true,
                        ..Default::default()
                    },
                )?;
                if outcome.status.persisted_mutation() {
                    *ws = outcome.workspace.clone();
                } else {
                    bail!(
                        "BUG: failed to apply head ref ({head_name}). Failed with {:?}",
                        outcome.status
                    )
                }
            };

            let (did_rollback, _) = but_transaction::with_transaction_with_perm_only(
                ctx,
                meta,
                perm,
                DryRun::No,
                |mut tx| {
                    tx.create_reference(new_ref.as_ref(), None, |_| StackId::generate(), Some(0))?;

                    Ok(())
                },
            )?;

View on GitHub (pinned to 58e5313667)