{"record":{"id":"dc05ba3bd7c14b3f","repo":"gitbutlerapp/gitbutler","slug":"branch-no-longer-exists","errorCode":null,"errorMessage":"branch '{}' no longer exists","messagePattern":"branch '(.+?)' no longer exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/gitbutler-oplog/src/oplog.rs","lineNumber":673,"sourceCode":"    ) -> Result<gix::ObjectId> {\n        if let Some(branch) = stack.heads.last() {\n            branch_head_oid(branch, repo)\n        } else {\n            Ok(default_target_oid)\n        }\n    }\n\n    pub(super) fn sync_stack_heads_from_refs(stack: &mut Stack, repo: &gix::Repository) -> bool {\n        let mut changed = false;\n        for head in &mut stack.heads {\n            changed |= sync_branch_head_from_ref(head, repo).unwrap_or(false);\n        }\n        changed\n    }\n\n    fn branch_head_oid(branch: &StackBranch, repo: &gix::Repository) -> Result<gix::ObjectId> {\n        let Some(mut reference) = repo.try_find_reference(&branch.name)? else {\n            bail!(\"branch '{}' no longer exists\", branch.name);\n        };\n        Ok(reference.peel_to_commit()?.id)\n    }\n\n    pub(super) fn set_reference_to_stored_head(\n        branch: &StackBranch,\n        repo: &gix::Repository,\n    ) -> Result<()> {\n        repo.reference(\n            qualified_reference_name(&branch.name),\n            branch.head,\n            gix::refs::transaction::PreviousValue::Any,\n            \"GitButler reference\",\n        )?;\n        Ok(())\n    }\n\n    fn sync_branch_head_from_ref(branch: &mut StackBranch, repo: &gix::Repository) -> Result<bool> {","sourceCodeStart":655,"sourceCodeEnd":691,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/gitbutler-oplog/src/oplog.rs#L655-L691","documentation":"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.","triggerScenarios":"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.","commonSituations":"Users deleting GitButler-managed branches from the CLI or another tool; interrupted operations that remove refs but not stack metadata; cross-tool worktrees.","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"],"exampleFix":"# before: stack metadata lists branch 'feature-x' but the ref is gone\n# after: recreate it at the stored head, or drop it from the stack\ngit branch feature-x <stored-head-oid>\n# or in the GitButler UI: delete branch 'feature-x' from the stack","handlingStrategy":"validation","validationCode":"for head in &stack.heads {\n    if repo.try_find_reference(&head.branch_name)?.is_none() {\n        return Err(anyhow::anyhow!(\"stack branch {} was deleted; recreate or remove it\", head.branch_name));\n    }\n}","typeGuard":"fn all_stack_refs_exist(stack: &Stack, repo: &gix::Repository) -> bool {\n    stack.heads.iter().all(|h| repo.try_find_reference(&h.branch_name).ok().flatten().is_some())\n}","tryCatchPattern":"if let Err(err) = branch_head_oid(&branch, &repo) {\n    if err.to_string().contains(\"no longer exists\") {\n        // prune the deleted branch from the stack, or recreate the ref\n    }\n}","preventionTips":["Delete GitButler stack branches through the app so metadata stays consistent","After external git surgery, reconcile stacks before triggering a sync"],"tags":["rust","gitbutler","stacks","missing-branch","sync"],"backgroundTag":"deleted-git-branch","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}