{"record":{"id":"0694d8ad2cafd70f","repo":"gitbutlerapp/gitbutler","slug":"snapshot-additional-ref-is-not-a-local-branch","errorCode":null,"errorMessage":"snapshot additional ref is not a local branch","messagePattern":"snapshot additional ref is not a local branch","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/gitbutler-oplog/src/oplog.rs","lineNumber":558,"sourceCode":"}\n\nstruct SnapshotReference {\n    ref_name: gix::refs::FullName,\n    target: Option<gix::ObjectId>,\n}\n\nfn snapshot_reference(\n    snapshot_tree: &gix::Tree<'_>,\n    repo: &gix::Repository,\n) -> Result<Option<SnapshotReference>> {\n    let Some(name_entry) = snapshot_tree.lookup_entry_by_path(\"additional-ref/name\")? else {\n        return Ok(None);\n    };\n    let name_blob = repo.find_blob(name_entry.id())?;\n    let ref_name = gix::refs::FullName::try_from(name_blob.data.as_bstr())\n        .context(\"snapshot additional ref is invalid\")?;\n    if ref_name.category() != Some(gix::refs::Category::LocalBranch) {\n        bail!(\"snapshot additional ref is not a local branch\");\n    }\n    let target = snapshot_tree\n        .lookup_entry_by_path(\"additional-ref/target\")?\n        .map(|entry| {\n            let blob = repo.find_blob(entry.id())?;\n            gix::ObjectId::from_hex(&blob.data).context(\"snapshot additional ref target is invalid\")\n        })\n        .transpose()?;\n    if target.is_some_and(|target| target.is_null()) {\n        bail!(\"snapshot additional ref target is null\");\n    }\n    Ok(Some(SnapshotReference { ref_name, target }))\n}\n\nfn snapshot_checkout(\n    snapshot_tree: &gix::Tree<'_>,\n    repo: &gix::Repository,\n) -> Result<Option<SnapshotCheckout>> {","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/gitbutler-oplog/src/oplog.rs#L540-L576","documentation":"During snapshot restore, snapshot_reference reads 'additional-ref' entries saved in the snapshot tree. The ref's name blob must parse as a FullName and must be a local branch (Category::LocalBranch); only local branches are restored as additional refs. Anything else (tag, remote branch, malformed name) bails with this message.","triggerScenarios":"restore_snapshot encountering an additional-ref whose stored name parses to a non-local-branch category, e.g. refs/remotes/origin/main, refs/tags/v1, or a fully malformed ref string that somehow parses to another category.","commonSituations":"Snapshots written by a version that stored other ref kinds as additional refs; manually edited snapshot trees; corrupted oplog data; custom tooling writing snapshot entries.","solutions":["Inspect the snapshot tree's additional-ref/name blob and correct it to a local branch name (refs/heads/...).","Restore from an alternate snapshot that lacks the offending additional ref.","Skip restoring the offending additional ref (manual re-creation of the branch afterwards).","If produced by a stock GitButler snapshot, report as a snapshot-format bug with the snapshot id."],"exampleFix":"// before (additional-ref/name blob in snapshot)\n\"refs/remotes/origin/feature\"\n// after\n\"refs/heads/feature\"","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match restore_snapshot(&ctx, id) {\n    Err(e) if e.to_string().contains(\"additional ref is not a local branch\") => {\n        // restore without that ref, or pick a different snapshot\n    }\n    other => other?,\n}","preventionTips":["Only record local branches as additional refs in snapshots","Validate ref category when writing snapshot additional-ref entries","Keep snapshot format changes backward-compatible across versions"],"tags":["git","oplog","snapshot-restore","ref-format","validation"],"backgroundTag":"incompatible-source-type","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}