{"record":{"id":"7d256fd5ca4d8257","repo":"GitoxideLabs/gitoxide","slug":"cursor-is-delta-only-allows-deltas-here","errorCode":null,"errorMessage":"cursor.is_delta() only allows deltas here","messagePattern":"cursor\\.is_delta\\(\\) only allows deltas here","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-pack/src/data/file/decode/entry.rs","lineNumber":289,"sourceCode":"            use crate::data::entry::Header;\n            cursor = match cursor.header {\n                Header::OfsDelta { base_distance } => {\n                    self.entry(cursor.checked_base_pack_offset(base_distance).ok_or(\n                        crate::data::entry::decode::Error::Corrupt {\n                            message: \"an ofs-delta base distance pointing before pack start\",\n                        },\n                    )?)?\n                }\n                Header::RefDelta { base_id } => match resolve(base_id.as_ref(), out) {\n                    Some(ResolvedBase::InPack(entry)) => entry,\n                    Some(ResolvedBase::OutOfPack { end, kind }) => {\n                        base_buffer_size = Some(end);\n                        object_kind = Some(kind);\n                        break;\n                    }\n                    None => return Err(Error::DeltaBaseUnresolved(base_id)),\n                },\n                _ => unreachable!(\"cursor.is_delta() only allows deltas here\"),\n            };\n        }\n\n        // This can happen if the cache held the first entry itself\n        // We will just treat it as an object then, even though it's technically incorrect.\n        if chain.is_empty() {\n            return Ok(Outcome::from_object_entry(\n                object_kind.expect(\"object kind as set by cache\"),\n                &first_entry,\n                consumed_input.expect(\"consumed bytes as set by cache\"),\n            ));\n        }\n\n        // First pass will decompress all delta data and keep it in our output buffer\n        // [<possibly resolved base object>]<delta-1..delta-n>...\n        // so that we can find the biggest result size.\n        let total_delta_data_size: usize = total_delta_data_size.try_into().map_err(|_| Error::OutOfMemory)?;\n","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-pack/src/data/file/decode/entry.rs#L271-L307","documentation":"`resolve_deltas` in `gix-pack` decodes a pack entry's delta chain; `cursor.is_delta()` guarantees the match only sees OFS/REF deltas, so the default arm panics. Firing means a non-delta entry kind reached delta resolution — a decoder invariant violation, typically from corrupted in-memory cursor state rather than bad pack data (bad data yields `Error::DeltaBaseUnresolved` instead).","triggerScenarios":"Calling `gix_pack::data::File::decode_entry` on an entry whose cursor claims `is_delta()` but whose resolved kind is neither OFS nor REF delta — practically only after pack cache or decoder bugs.","commonSituations":"Not reachable with well-formed packs; could appear with a corrupted pack file interacting with cache assumptions or a version mismatch in pack decoding code.","solutions":["Verify pack integrity (e.g. `git fsck`, `gix repo verify`) if you suspect corruption.","Report upstream with the pack file and entry that triggered it.","Update `gix-pack` to the latest version.","If maintaining, map the default arm to `Error::DeltaBaseUnresolved` or a new decode error instead of panicking."],"exampleFix":"// before\n_ => unreachable!(\"cursor.is_delta() only allows deltas here\"),\n// after\n_ => return Err(Error::DeltaBaseUnresolved(base_id)),","handlingStrategy":"try-catch","validationCode":"// Check pack integrity before heavy decoding\n// gix_pack::data::File::verify_checksum(...) or git fsck on the repository","typeGuard":null,"tryCatchPattern":"let res = std::panic::catch_unwind(|| file.decode_entry(entry, ...));\n// on panic: treat pack as suspect, re-verify or re-clone","preventionTips":["Verify pack checksums when consuming untrusted packs","Keep gix-pack and gix-odb versions aligned","Report panics with the offending pack file"],"tags":["rust","panic","internal-invariant","pack-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"}