gitbutlerapp/gitbutler · error
branch '{}' no longer exists
Error message
branch '{}' no longer exists What it means
During stack synchronization, each stored stack head oid is refreshed from the actual git reference via `branch_head_oid`. This bail fires when the reference for a stack branch cannot be found at all: the branch was deleted from the repository while the stack metadata still lists it.
Source
Thrown at crates/gitbutler-oplog/src/oplog.rs:673
) -> Result<gix::ObjectId> {
if let Some(branch) = stack.heads.last() {
branch_head_oid(branch, repo)
} else {
Ok(default_target_oid)
}
}
pub(super) fn sync_stack_heads_from_refs(stack: &mut Stack, repo: &gix::Repository) -> bool {
let mut changed = false;
for head in &mut stack.heads {
changed |= sync_branch_head_from_ref(head, repo).unwrap_or(false);
}
changed
}
fn branch_head_oid(branch: &StackBranch, repo: &gix::Repository) -> Result<gix::ObjectId> {
let Some(mut reference) = repo.try_find_reference(&branch.name)? else {
bail!("branch '{}' no longer exists", branch.name);
};
Ok(reference.peel_to_commit()?.id)
}
pub(super) fn set_reference_to_stored_head(
branch: &StackBranch,
repo: &gix::Repository,
) -> Result<()> {
repo.reference(
qualified_reference_name(&branch.name),
branch.head,
gix::refs::transaction::PreviousValue::Any,
"GitButler reference",
)?;
Ok(())
}
fn sync_branch_head_from_ref(branch: &mut StackBranch, repo: &gix::Repository) -> Result<bool> {View on GitHub (pinned to caf1f223d3)
Solutions
- Recreate the branch at its stored head (`git branch <name> <stored-head-oid>`) and retry the sync
- Or remove the deleted branch from the stack / delete the stack in the UI so metadata matches the repository
- If branches vanish repeatedly, check for concurrent git tooling deleting refs behind GitButler's back
Example fix
# before: stack metadata lists branch 'feature-x' but the ref is gone # after: recreate it at the stored head, or drop it from the stack git branch feature-x <stored-head-oid> # or in the GitButler UI: delete branch 'feature-x' from the stack
Defensive patterns
Strategy: validation
Validate before calling
for head in &stack.heads {
if repo.try_find_reference(&head.branch_name)?.is_none() {
return Err(anyhow::anyhow!("stack branch {} was deleted; recreate or remove it", head.branch_name));
}
} Type guard
fn all_stack_refs_exist(stack: &Stack, repo: &gix::Repository) -> bool {
stack.heads.iter().all(|h| repo.try_find_reference(&h.branch_name).ok().flatten().is_some())
} Try / catch
if let Err(err) = branch_head_oid(&branch, &repo) {
if err.to_string().contains("no longer exists") {
// prune the deleted branch from the stack, or recreate the ref
}
} Prevention
- Delete GitButler stack branches through the app so metadata stays consistent
- After external git surgery, reconcile stacks before triggering a sync
When it happens
Trigger: Stack head syncing for a branch deleted externally — `git branch -D`, another Git client, or cleanup after a failed push/rebase — while the stack's stored metadata still references it.
Common situations: Users deleting GitButler-managed branches from the CLI or another tool; interrupted operations that remove refs but not stack metadata; cross-tool worktrees.
Related errors
- Error ${error.response.status}: ${error.message}
- Invalid message format
- Cannot compute diff specs for stacks
- Failed to communicate with LM Studio server: ${error instanc
- Invalid response: ${JSON.stringify(result)}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/dc05ba3bd7c14b3f.
Report an issue: GitHub.