gitbutlerapp/gitbutler · error
Failed to apply branch: {outcome}
Error message
Failed to apply branch: {outcome} What it means
In the status TUI's stack-mode apply flow (crates/but/src/command/legacy/status/tui/app/stack_mode.rs:406), apply::run returning ApplyOutcome::ConflictAborted(outcome) is converted to a hard error. The abort means applying the selected branch onto the current workspace would produce merge conflicts, so the operation was rolled back without touching the worktree; the outcome detail lists what conflicted.
Source
Thrown at crates/but/src/command/legacy/status/tui/app/stack_mode.rs:406
b.has_local
.cmp(&a.has_local)
.then_with(|| b.updated_at.cmp(&a.updated_at))
.then_with(|| a.name.cmp(&b.name))
});
let Some(items) = NonEmpty::from_vec(branches) else {
return Ok(());
};
let picker = FuzzyPicker::new(items, self.theme, |item, ctx, messages| {
let branch = {
let repo = ctx.repo.get()?;
BranchArg(item.name.clone()).resolve_legacy_top_level_apply_branch_name(&repo)?
};
let mut guard = ctx.exclusive_worktree_access();
match apply::run(ctx, guard.write_permission(), ApplyOperation { branch })? {
ApplyOutcome::ConflictAborted(outcome) => {
anyhow::bail!("Failed to apply branch: {outcome}")
}
ApplyOutcome::AlreadyApplied { .. } | ApplyOutcome::Applied { .. } => {}
}
messages.extend([
Message::EnterNormalModeAfterConfirmingOperation,
Message::Reload(
Some(SelectAfterReload::Branch(item.name)),
ReloadCause::Mutation,
),
]);
Ok(())
});
self.modal = Some(Modal::ApplyStackPicker {
picker: Box::new(picker),
key_binds: fuzzy_picker_key_binds(),
});View on GitHub (pinned to caf1f223d3)
Solutions
- Read the conflict detail in the outcome message to identify the clashing files, then unapply the conflicting stack and apply branches in an order that avoids the overlap.
- Update/rebase the branch onto the current target so it applies cleanly, then retry.
- Move the conflicting commits to a separate stack or apply the branch in a dedicated worktree.
Example fix
# before: stacks 'auth' and 'db' both edit schema.sql # stack-mode -> apply 'db' -> Failed to apply branch: conflict... # after but branch unapply auth # or move conflicting commits # then apply 'db', then re-apply 'auth' resolving order
Defensive patterns
Strategy: try-catch
Try / catch
match apply::run(ctx, guard.write_permission(), ApplyOperation { branch })? {
ApplyOutcome::ConflictAborted(outcome) => {
// surface outcome (conflicting files), suggest unapply/reorder, keep worktree untouched
Err(anyhow::anyhow!("Failed to apply branch: {outcome}"))
}
ApplyOutcome::AlreadyApplied { .. } | ApplyOutcome::Applied { .. } => Ok(()),
} Prevention
- Apply branches touching disjoint files, or unapply conflicting stacks first.
- Rebase/update branches onto the current target before applying.
- Treat ConflictAborted as a clean rollback: the worktree is unchanged, so retry after reordering is safe.
When it happens
Trigger: Applying a branch via the stack-mode fuzzy picker when its changes conflict with already-applied workspace branches — overlapping edits to the same files or hunks.
Common situations: Two stacks editing the same lines; applying a branch forked before recent workspace changes; stale branches that need rebasing onto the target.
Related errors
- merge conflict when computing workspace tree
- Encountered conflict when merging tree {tree_to_merge}{detai
- When using OpenRouter, you must provide a valid API key
- Error ${error.response.status}: ${error.message}
- Invalid message format
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/63dace1935d1f7b8.
Report an issue: GitHub.