{"record":{"id":"71bdd8e6481248ce","repo":"gitbutlerapp/gitbutler","slug":"can-t-handle-reference-rn-of-category-catego","errorCode":null,"errorMessage":"Can't handle reference '{rn}' of category '{category:?}'","messagePattern":"Can't handle reference '(.+?)' of category '(.+?)'","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-graph/src/debug.rs","lineNumber":95,"sourceCode":"                    let new_short_name = name_mapping\n                        .entry(short_name.to_owned())\n                        .or_insert_with(|| int_to_alpha(num_names).into());\n                    new_name.push_byte(b'/');\n                    new_name.push_str(new_short_name);\n                    *rn = gix::refs::FullName::try_from(new_name.as_bstr())\n                        .expect(\"Our replacement names are always valid\");\n                }\n\n                Category::Note\n                | Category::PseudoRef\n                | Category::MainPseudoRef\n                | Category::MainRef\n                | Category::LinkedPseudoRef { .. }\n                | Category::LinkedRef { .. }\n                | Category::Bisect\n                | Category::Rewritten\n                | Category::WorktreePrivate => {\n                    bail!(\"Can't handle reference '{rn}' of category '{category:?}'\");\n                }\n            }\n            Ok(())\n        };\n        for node in self.inner.node_weights_mut() {\n            if let Some(ri) = node.ref_info.as_mut() {\n                anon(&mut ri.ref_name)?;\n            }\n            if let Some(rn) = node.remote_tracking_ref_name.as_mut() {\n                anon(rn)?;\n            }\n            for ri in node.commits.iter_mut().flat_map(|c| c.refs.iter_mut()) {\n                anon(&mut ri.ref_name)?;\n            }\n            if let Some(SegmentMetadata::Workspace(md)) = node.metadata.as_mut() {\n                for rn in md\n                    .stacks\n                    .iter_mut()","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-graph/src/debug.rs#L77-L113","documentation":"Thrown by the anonymization walk in but-graph's debug module (crates/but-graph/src/debug.rs:95). When producing anonymized debug output (e.g., `but graph debug` visualizations), every reference name in the graph is rewritten to a stable fake name; the match on Category simply has no anonymization arm for Note, PseudoRef, MainPseudoRef, MainRef, LinkedPseudoRef, LinkedRef, Bisect, Rewritten, or WorktreePrivate refs. Hitting it means the repository graph contains one of those ref kinds and the anonymizer chose to fail loudly rather than leak or mangle the real name.","triggerScenarios":"Running graph debug/anonymization on a repository that has refs/notes/*, refs/bisect/* (mid git bisect), refs/rewritten/* (from rebase --update-refs), worktree-private refs (per-worktree HEAD/bisect state), or pseudo-refs like FETCH_HEAD/MERGE_REF at non-standard names; linked worktrees with their own branch namespaces.","commonSituations":"Debugging a graph dump right after a `git bisect` or `git rebase --update-refs` session; repos with git-notes enabled; running the anonymizer in CI fixtures that synthesize exotic refs; new but-graph versions adding categories without extending the debug anonymizer.","solutions":["Inspect which ref triggered it (the message names ref and category): `git for-each-ref --format='%(refname)' | grep -E 'notes|bisect|rewritten'`","Clean the transient state: finish or reset `git bisect reset`, complete the rebase, drop stale refs/rewritten and refs/notes entries you do not need, then rerun","If you need anonymized output despite those refs, extend the match in debug.rs with mapping arms for the listed categories","Otherwise use the non-anonymized debug output for that repo"],"exampleFix":"// before (debug.rs) — categories with no anonymization arm bail\nCategory::Note | Category::Bisect | Category::Rewritten | Category::WorktreePrivate => {\n    bail!(\"Can't handle reference '{rn}' of category '{category:?}'\");\n}\n\n// after — map them to a category-tagged placeholder instead of failing\nCategory::Note => {\n    *rn = gix::refs::FullName::try_from(format!(\"refs/anon-notes/{}\", counter.next()))\n        .expect(\"generated name is valid\");\n}\nCategory::Bisect | Category::Rewritten | Category::WorktreePrivate\n| Category::PseudoRef | Category::MainPseudoRef | Category::MainRef\n| Category::LinkedPseudoRef { .. } | Category::LinkedRef { .. } => {\n    *rn = gix::refs::FullName::try_from(format!(\"refs/anon/{category:?}/{}\", counter.next()))\n        .expect(\"generated name is valid\");\n}","handlingStrategy":"fallback","validationCode":"// Pre-filter refs the anonymizer cannot handle before generating debug output\nuse but_graph::Category;\nfn anonymizable(name: &gix::refs::FullName) -> bool {\n    !matches!(\n        name.category(),\n        Some(Category::Note)\n            | Some(Category::PseudoRef)\n            | Some(Category::MainPseudoRef)\n            | Some(Category::MainRef)\n            | Some(Category::LinkedPseudoRef { .. })\n            | Some(Category::LinkedRef { .. })\n            | Some(Category::Bisect)\n            | Some(Category::Rewritten)\n            | Some(Category::WorktreePrivate)\n    )\n}","typeGuard":null,"tryCatchPattern":"match graph_debug.anonymize() { // conceptual\n    Ok(out) => out,\n    Err(err) if err.to_string().contains(\"Can't handle reference\") => {\n        tracing::warn!(\"repo has non-anonymizable refs (notes/bisect/rewritten/worktree); emitting non-anonymized output\");\n        graph_debug.raw()\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Run `git bisect reset` and finish rebases before capturing anonymized graph dumps","Prune refs/notes, refs/rewritten, and stale worktree refs you do not need before debugging"],"tags":["but-graph","debug","anonymization","git-refs","rust"],"backgroundTag":"unsupported-reference-category","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}