{"record":{"id":"cd50128c74f7522f","repo":"GitoxideLabs/gitoxide","slug":"at-least-one-delta-chain-item","errorCode":null,"errorMessage":"at least one delta chain item","messagePattern":"at least one delta chain item","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gix-pack/src/data/file/decode/entry.rs","lineNumber":436,"sourceCode":"            delta_idx,\n            Delta {\n                data,\n                base_size,\n                result_size,\n                ..\n            },\n        ) in chain.into_iter().rev().enumerate()\n        {\n            let data = &mut instructions[data];\n            if delta_idx + 1 == chain_len {\n                last_result_size = Some(result_size);\n            }\n            delta::apply(&source_buf[..base_size], &mut target_buf[..result_size], data)?;\n            // use the target as source for the next delta\n            std::mem::swap(&mut source_buf, &mut target_buf);\n        }\n\n        let last_result_size = last_result_size.expect(\"at least one delta chain item\");\n        // uneven chains leave the target buffer after the source buffer\n        // FIXME(Performance) If delta-chains are uneven, we know we will have to copy bytes over here\n        //      Instead we could use a different start buffer, to naturally end up with the result in the\n        //      right one.\n        //      However, this is a bit more complicated than just that - you have to deal with the base\n        //      object, which should also be placed in the second buffer right away. You don't have that\n        //      control/knowledge for out-of-pack bases, so this is a special case to deal with, too.\n        //      Maybe these invariants can be represented in the type system though.\n        if chain_len % 2 == 1 {\n            // this seems inverted, but remember: we swapped the buffers on the last iteration\n            target_buf[..last_result_size].copy_from_slice(&source_buf[..last_result_size]);\n        }\n        debug_assert!(out.len() >= last_result_size);\n        out.truncate(last_result_size);\n\n        let object_kind = object_kind.expect(\"a base object as root of any delta chain that we are here to resolve\");\n        let consumed_input = consumed_input.expect(\"at least one decompressed delta object\");\n        cache.put(","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-pack/src/data/file/decode/entry.rs#L418-L454","documentation":"A `expect()` panic asserting `last_result_size` is set after the delta application loop in `resolve_deltas`. The loop runs once per chain item, and the empty-chain case already returned earlier, so at least one delta must have been applied. A `None` here means the chain was mutated mid-flight — a decoder invariant violation.","triggerScenarios":"Only via a code defect: `decode_entry` -> `resolve_deltas` reaching the post-loop code with an empty delta chain, which the earlier `if chain.is_empty()` early-return should prevent.","commonSituations":"Essentially unreachable for library users; appears when modifying `resolve_deltas` or fuzzing deeply corrupted packs that defeat the early return.","solutions":["Update gix-pack to a current release","Ensure packs are not truncated/corrupted before decoding (run pack verification)","File a bug with a reproducing pack if ever observed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// validate the pack before decoding: open via gix_pack::data::File::at(path)? and run verify()","typeGuard":null,"tryCatchPattern":"match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| pack.decode_entry(id, &mut out, ...))) { Ok(v) => v, Err(_) => /* fallback: read object via git or another pack */ }","preventionTips":["Verify packs before heavy decoding","Avoid truncated or corrupted pack files","Report any occurrence as an upstream bug"],"tags":["rust","panic","internal-invariant","gix-pack","delta-resolution"],"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"}