GitoxideLabs/gitoxide · error

number of commits in CDAT chunk to fit in 32 bits

Error message

number of commits in CDAT chunk to fit in 32 bits

What it means

During commit-graph file initialization, the number of entries in the CDAT (commit data) chunk — chunk size divided by entry size — is cast to u32. Since the format stores commit counts in 32 bits and the chunk was size-validated beforehand, this conversion is expected to always fit. The panic indicates the chunk size is absurdly large, i.e. a corrupt or malicious commit-graph file.

Solutions

  1. Regenerate the commit-graph (`git commit-graph write`) or delete it
  2. Treat commit-graph load failure as non-fatal in application code and fall back to raw object reads
  3. If reproducible with a git-produced file, report upstream

Example fix

// before
let graph = gix_commitgraph::File::at(path, hash)?;
// after
let graph = gix_commitgraph::File::at(path, hash).ok(); // graphs are optional caches
Defensive patterns

Strategy: fallback

Validate before calling

let meta = std::fs::metadata(path)?; if meta.len() > u32::MAX as u64 { eprintln!("implausibly large commit-graph; skipping"); }

Try / catch

let graph = match gix_commitgraph::File::at(path, hash).map_err(|e| e.into_error()) { Ok(g) => Some(g), Err(e) => { log::warn!("commit-graph unusable: {e}"); None } };

Prevention

When it happens

Trigger: Calling `gix_commitgraph::File::at()` on a commit-graph whose CDAT chunk size / entry size exceeds u32::MAX — possible only with a corrupt or crafted file (or an internal validation bug).

Common situations: Truncated or corrupted commit-graph files, disk corruption, hand-edited files, fuzz inputs.

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


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/db0e4e1adbe25bc4. Report an issue: GitHub.

Appendix: source

Thrown at gix-commitgraph/src/file/init.rs:99

                }
                Ok(chunk_range.start)
            })
            .ok()
            .transpose()?;

        let (commit_data_offset, commit_data_count): (_, u32) = chunks
            .validated_usize_offset_by_id(COMMIT_DATA_CHUNK_ID, |chunk_range| {
                let chunk_size = chunk_range.len();

                let entry_size = object_hash.len_in_bytes() + COMMIT_DATA_ENTRY_SIZE_SANS_HASH;
                if chunk_size % entry_size != 0 {
                    return Err(message!("Commit-graph chunk {COMMIT_DATA_CHUNK_ID:?} has invalid size: chunk size {chunk_size} is not a multiple of {entry_size}").raise())
                }
                Ok((
                    chunk_range.start,
                    (chunk_size / entry_size)
                        .try_into()
                        .expect("number of commits in CDAT chunk to fit in 32 bits"),
                ))
            })??;

        let fan_offset = chunks
            .validated_usize_offset_by_id(OID_FAN_CHUNK_ID, |chunk_range| {
                let chunk_size = chunk_range.len();

                let expected_size = 4 * FAN_LEN;
                if chunk_size != expected_size {
                    return Err(message!("Commit-graph chunk {OID_FAN_CHUNK_ID:?} has invalid size: expected chunk length {expected_size}, got {chunk_size}").raise())
                }
                Ok(chunk_range.start)
            })?
            .or_raise(|| message("Error getting offset for OID fan chunk"))?;

        let (oid_lookup_offset, oid_lookup_count): (_, u32) = chunks
            .validated_usize_offset_by_id(OID_LOOKUP_CHUNK_ID, |chunk_range| {
                let chunk_size = chunk_range.len();

View on GitHub (pinned to e73179060b)