{"record":{"id":"956c0590cfc2a356","repo":"gitbutlerapp/gitbutler","slug":"failed-to-parse-branch-ref-bytes-e","errorCode":null,"errorMessage":"Failed to parse branch_ref_bytes: {e}","messagePattern":"Failed to parse branch_ref_bytes: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-hunk-assignment/src/lib.rs","lineNumber":128,"sourceCode":"            .hunk_header\n            .as_ref()\n            .and_then(|h| serde_json::from_str(h).ok());\n        let legacy_stack_id = value\n            .stack_id\n            .as_ref()\n            .and_then(|id| uuid::Uuid::parse_str(id).ok())\n            .map(StackId::from);\n        Ok(HunkAssignment {\n            id: value.id.map(|id| Uuid::parse_str(&id)).transpose()?,\n            hunk_header: header,\n            path: value.path,\n            path_bytes: value.path_bytes.into(),\n            stack_id: legacy_stack_id,\n            branch_ref_bytes: value\n                .branch_ref_bytes\n                .map(|b| gix::refs::FullName::try_from(BString::from(b)))\n                .transpose()\n                .map_err(|e| anyhow::anyhow!(\"Failed to parse branch_ref_bytes: {e}\"))?,\n            line_nums_added: None,   // derived data (not persisted)\n            line_nums_removed: None, // derived data (not persisted)\n            diff: None,              // derived data (not persisted)\n        })\n    }\n}\n\nimpl TryFrom<HunkAssignment> for but_db::HunkAssignment {\n    type Error = anyhow::Error;\n    fn try_from(value: HunkAssignment) -> Result<Self, Self::Error> {\n        let header = value\n            .hunk_header\n            .map(|h| {\n                serde_json::to_string(&h)\n                    .map_err(|e| anyhow::anyhow!(\"Failed to serialize hunk_header: {e}\"))\n            })\n            .transpose()?;\n        Ok(but_db::HunkAssignment {","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-hunk-assignment/src/lib.rs#L110-L146","documentation":"When converting a stored database HunkAssignment row into the domain HunkAssignment, the persisted branch_ref_bytes must be a valid gix::refs::FullName (e.g. refs/heads/...). If parsing fails, the row contains a malformed ref name and the conversion aborts with this error.","triggerScenarios":"TryFrom<but_db::HunkAssignment> for HunkAssignment encountering branch_ref_bytes that does not parse as a gix::refs::FullName — corrupt or hand-edited DB rows, or rows written by an older version with a different ref format.","commonSituations":"Schema/version drift after upgrading GitButler; manual DB edits; bugs in earlier writers persisting invalid ref strings.","solutions":["Fix or clear the malformed branch_ref_bytes value in the HunkAssignment table row","Re-run assignment so rows are rewritten with valid refs","Check for version mismatch between the tool that wrote the DB and the reader; upgrade/downgrade accordingly"],"exampleFix":"// before\n// row.branch_ref_bytes = \"heads/my-branch\" (invalid, missing refs/)\n// after\n// row.branch_ref_bytes = \"refs/heads/my-branch\"","handlingStrategy":"try-catch","validationCode":"if let Some(b) = &row.branch_ref_bytes {\n    if gix::refs::FullName::try_from(BString::from(b.clone())).is_err() {\n        eprintln!(\"Skipping row with malformed branch_ref_bytes: {b:?}\");\n    }\n}","typeGuard":"fn valid_ref(b: &BString) -> Option<gix::refs::FullName> {\n    gix::refs::FullName::try_from(b.clone()).ok()\n}","tryCatchPattern":"match HunkAssignment::try_from(row) {\n    Ok(a) => use(a),\n    Err(e) if e.to_string().contains(\"branch_ref_bytes\") => {\n        log::warn!(\"corrupt row skipped: {e}\");\n        // re-assign or repair the row\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always write refs in full refs/heads/... form","Validate ref bytes before persisting to the DB","Handle schema/version drift between writer and reader versions"],"tags":["parsing","git","database","deserialization"],"backgroundTag":"invalid-identifier-format","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"}