{"record":{"id":"347b80e7bc724ea9","repo":"GitoxideLabs/gitoxide","slug":"prior-validation","errorCode":null,"errorMessage":"prior validation","messagePattern":"prior validation","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gix-ref/src/store/file/loose/reference/decode.rs","lineNumber":92,"sourceCode":"/// If neither reference form can be parsed, an error is returned.\nfn parse(mut i: &[u8], object_hash: gix_hash::Kind) -> Result<MaybeUnsafeState, ()> {\n    if let Some(rest) = i.strip_prefix(b\"ref: \") {\n        i = rest;\n        while i.first() == Some(&b' ') {\n            i = &i[1..];\n        }\n        let path_end = i\n            .iter()\n            .position(|b| *b == b'\\0' || *b == b'\\r' || *b == b'\\n')\n            .unwrap_or(i.len());\n        let path = i[..path_end].into();\n        Ok(MaybeUnsafeState::UnvalidatedPath(path))\n    } else {\n        let hex = hex_hash(&mut i, object_hash)?;\n        if i.first().is_some_and(u8::is_ascii_hexdigit) {\n            return Err(());\n        }\n        Ok(MaybeUnsafeState::Id(ObjectId::from_hex(hex).expect(\"prior validation\")))\n    }\n}\n","sourceCodeStart":74,"sourceCodeEnd":95,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-ref/src/store/file/loose/reference/decode.rs#L74-L95","documentation":"A Rust `expect()` panic in the loose-ref `parse` helper (gix-ref/store/file/loose/reference/decode.rs), called when building a `Reference` via `try_from_path`. `hex_hash` already validated that the input starts with a correctly sized run of hex digits for `object_hash`, so `ObjectId::from_hex` must succeed; `expect(\"prior validation\")` documents that invariant. It panics only if `hex_hash` accepted hex digits whose count differs from what `from_hex` requires — a hash-kind/length mismatch between the validation step and the decoder.","triggerScenarios":"Parsing a loose ref file whose leading hex id length matches `hex_hash`'s acceptance but not `ObjectId::from_hex`'s expectation — e.g. the caller supplied a `gix_hash::Kind` different from the one the ref file was written with, or `hex_hash`'s validation window is inconsistent with the kind.","commonSituations":"SHA-256 repositories parsed with SHA-1 kind (or vice versa); corrupted loose ref files with truncated/overlong hex ids; hand-edited `.git/refs/**` files.","solutions":["Pass the repository's actual `object_hash` kind to `Reference::try_from_path` rather than a hard-coded kind.","Verify the loose ref file contents (a direct ref must be exactly one valid 40/64-char hex id) and repair it (`git symbolic-ref`/`git update-ref`).","Run `git fsck` to identify and fix corrupted refs.","Report upstream with the ref file bytes if kinds match and it still panics."],"exampleFix":"// before\nReference::try_from_path(name, contents, gix_hash::Kind::Sha1)? // repo is Sha256 -> panic\n// after\nReference::try_from_path(name, contents, repo.object_hash())?","handlingStrategy":"validation","validationCode":"// use the repo's real hash kind when decoding loose refs\nlet kind = repo.object_hash();\nReference::try_from_path(name, contents, kind).map_err(|e| ...)?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass the matching gix_hash::Kind to try_from_path","Run git fsck to catch corrupted loose refs","Avoid hand-editing files under .git/refs"],"tags":["rust","panic","loose-refs","hex-decoding"],"backgroundTag":"internal-invariant-violation","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}