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
- Retry the command — transient locks or concurrent edits often resolve on a second attempt
- Run `but status` / re-open the workspace to refresh stale state, then retry
- Check for and dismiss external git processes touching the repo, then retry
- 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
- Avoid running multiple but/IDE workspace mutations concurrently
- Refresh workspace state (but status) after external git operations like rebase/reset
- Report reproducible occurrences upstream — the BUG prefix marks an internal invariant break
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
- Ad-hoc (single-branch) branch moves are not supported…
- Branch ' ' cannot be created: the target commit ( ) already…
- BranchNotFound
- Cannot add the target
- Cannot create reference on unborn branch
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)