GitoxideLabs/gitoxide · warning
at least one decompressed delta object
Error message
at least one decompressed delta object
What it means
A `expect()` panic asserting `consumed_input` is present after resolving deltas, so the resolved object can be put into the delta cache together with the number of input bytes it consumed. If the first (base) delta was decompressed, consumed bytes are always recorded; `None` indicates a broken internal state.
Solutions
- Update gix-pack
- Avoid patching the first-pass decompress loop without preserving consumed_input assignment
- Report upstream with a reproducer if ever hit
Defensive patterns
Strategy: try-catch
Try / catch
let r = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| pack.decode_entry(id, &mut out, ...)));
if r.is_err() { eprintln!("consumed-input invariant violated"); } Prevention
- Use stock decode paths
- Keep gix-pack current
- Treat occurrences as library bugs
When it happens
Trigger: Same path as errorIndex 464: `decode_entry` -> `resolve_deltas` finishing with at least one decompressed delta but missing consumption bookkeeping — only via a code defect.
Common situations: Unreachable in normal use; observed in gix-pack development or when altering the first-pass decompression loop.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- at least one delta chain item
- a base object as root of any delta chain that we are here…
- a non-delta entry
- object kind as set by cache
- consumed bytes as set by cache
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/0f3c5011f35d3b2b.
Report an issue: GitHub.
Appendix: source
Thrown at gix-pack/src/data/file/decode/entry.rs:453
let last_result_size = last_result_size.expect("at least one delta chain item");
// uneven chains leave the target buffer after the source buffer
// FIXME(Performance) If delta-chains are uneven, we know we will have to copy bytes over here
// Instead we could use a different start buffer, to naturally end up with the result in the
// right one.
// However, this is a bit more complicated than just that - you have to deal with the base
// object, which should also be placed in the second buffer right away. You don't have that
// control/knowledge for out-of-pack bases, so this is a special case to deal with, too.
// Maybe these invariants can be represented in the type system though.
if chain_len % 2 == 1 {
// this seems inverted, but remember: we swapped the buffers on the last iteration
target_buf[..last_result_size].copy_from_slice(&source_buf[..last_result_size]);
}
debug_assert!(out.len() >= last_result_size);
out.truncate(last_result_size);
let object_kind = object_kind.expect("a base object as root of any delta chain that we are here to resolve");
let consumed_input = consumed_input.expect("at least one decompressed delta object");
cache.put(
self.id,
first_entry.data_offset,
out.as_slice(),
object_kind,
consumed_input,
);
Ok(Outcome {
kind: object_kind,
// technically depending on the cache, the chain size is not correct as it might
// have been cut short by a cache hit. The caller must deactivate the cache to get
// actual results
num_deltas: chain_len as u32,
decompressed_size: first_entry.decompressed_size,
compressed_size: consumed_input,
object_size: last_result_size as u64,
})
}View on GitHub (pinned to e73179060b)