GitoxideLabs/gitoxide · info

an architecture able to hold 32 bits of integer

Error message

an architecture able to hold 32 bits of integer

What it means

When walking parents, an extended (extra) edge index (u32 from the EDGE chunk) is converted to usize and then multiplied by 4 to get the byte offset. The first expect panics if usize can't hold the 32-bit index (16-bit platforms); the second guards multiplication overflow. It appears in the recursive next() of the parent iterator.

Solutions

  1. Use a 64-bit platform
  2. Regenerate the commit-graph file (git commit-graph write) if it may be corrupt
  3. Use a fallible conversion and propagate an error instead of expecting
  4. Update gix-commitgraph if overflow handling should be graceful

Example fix

// before
let start_offset: usize = extra_edge_index
    .try_into()
    .expect("an architecture able to hold 32 bits of integer");
// after
let start_offset: usize = extra_edge_index
    .try_into()
    .map_err(|_| message("extra edge index does not fit into usize"))?;
Defensive patterns

Strategy: type-guard

Validate before calling

const _: () = assert!(std::mem::size_of::<usize>() >= 4, "extra-edge iteration requires 32-bit usize");

Type guard

fn can_hold_u32() -> bool { std::mem::size_of::<usize>() >= 4 }

Prevention

When it happens

Trigger: Iterating parents of a commit in a commit-graph file with an Extra Edge List on a platform where usize < u32, or with an index so large that *4 overflows usize (essentially only 16-bit or contrived cases).

Common situations: Corrupted commit-graph files with bogus extra-edge indices combined with small-address-space targets; not reachable on normal 64-bit systems.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at gix-commitgraph/src/file/commit.rs:154

                    ))),
                },
                ParentEdge::GraphPosition(pos) => {
                    self.state = ParentIteratorState::Second;
                    Some(Ok(pos))
                }
                ParentEdge::ExtraEdgeIndex(_) => Some(Err(message!(
                    "commit {}'s first parent is an extra edge index, which is invalid",
                    self.commit_data.id(),
                ))),
            },
            ParentIteratorState::Second => match self.commit_data.parent2 {
                ParentEdge::None => None,
                ParentEdge::GraphPosition(pos) => Some(Ok(pos)),
                ParentEdge::ExtraEdgeIndex(extra_edge_index) => {
                    if let Some(extra_edges_list) = self.commit_data.file.extra_edges_data() {
                        let start_offset: usize = extra_edge_index
                            .try_into()
                            .expect("an architecture able to hold 32 bits of integer");
                        let start_offset = start_offset
                            .checked_mul(4)
                            .expect("an extended edge index small enough to fit in usize");
                        if let Some(tail) = extra_edges_list.get(start_offset..) {
                            self.state = ParentIteratorState::Extra(tail.chunks(4));
                            // This recursive call is what blocks me from replacing ParentIterator
                            // with a std::iter::from_fn closure.
                            self.next()
                        } else {
                            Some(Err(message!(
                                "commit {}'s extra edges overflows the commit-graph file's extra edges list",
                                self.commit_data.id()
                            )))
                        }
                    } else {
                        Some(Err(message!(
                            "commit {} has extra edges, but commit-graph file has no extra edges list",
                            self.commit_data.id()

View on GitHub (pinned to e73179060b)