GitoxideLabs/gitoxide · error

must have been resolved

Error message

must have been resolved

What it means

`PackLocation::is_none()` (gix-pack `data/output/count/mod.rs`) is only valid after entry locations have been resolved: it unwraps the `LookedUp` variant and panics if the value is still `NotLookedUp`. Reaching the panic means code called `is_none()` before the counts' pack locations were computed (location resolution phase), which the API contract forbids.

Solutions

  1. Resolve counts first: run the pack-entry location resolution (e.g. `gix_pack::data::output::count::iter...]` with lookup enabled) before calling `is_none()`.
  2. Use a `match` on the `PackLocation` enum to handle `NotLookedUp` explicitly instead of `is_none()`.
  3. If locations are intentionally not needed, don't query them — configure the output so lookup is performed only when you consume locations.

Example fix

// before
if count.entry_pack_location.is_none() { ... }
// after
match &count.entry_pack_location {
    PackLocation::LookedUp(opt) => { /* use opt */ }
    PackLocation::NotLookedUp => { /* resolve locations first */ }
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Only call is_none() after verifying resolution state
fn locations_resolved(loc: &gix_pack::data::output::count::PackLocation) -> bool {
    matches!(loc, gix_pack::data::output::count::PackLocation::LookedUp(_))
}

Type guard

fn as_looked_up(loc: &PackLocation) -> Option<&Option<crate::data::entry::Location>> {
    match loc {
        PackLocation::LookedUp(opt) => Some(opt),
        PackLocation::NotLookedUp => None,
    }
}

Prevention

When it happens

Trigger: Calling `PackLocation::is_none()` on a `Count` whose `entry_pack_location` is `PackLocation::NotLookedUp` — i.e. counts produced with location lookup skipped or before `resolve_*`/iteration that populates locations.

Common situations: Calling `is_none()` on counts obtained without pack-location resolution (lookup disabled via options), calling it in custom sorting/partitioning code before running the resolution step, or after an API change reordered when locations get populated.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at gix-pack/src/data/output/count/mod.rs:20

use crate::data::output::Count;

/// Specifies how the pack location was handled during counting
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum PackLocation {
    /// We did not lookup this object
    NotLookedUp,
    /// The object was looked up and there may be a location in a pack, along with entry information
    LookedUp(Option<crate::data::entry::Location>),
}

impl PackLocation {
    /// Directly go through to `LookedUp` variant, panic otherwise
    pub fn is_none(&self) -> bool {
        match self {
            PackLocation::LookedUp(opt) => opt.is_none(),
            PackLocation::NotLookedUp => unreachable!("must have been resolved"),
        }
    }
    /// Directly go through to `LookedUp` variant, panic otherwise
    pub fn as_ref(&self) -> Option<&crate::data::entry::Location> {
        match self {
            PackLocation::LookedUp(opt) => opt.as_ref(),
            PackLocation::NotLookedUp => unreachable!("must have been resolved"),
        }
    }
}

impl Count {
    /// Create a new instance from the given `oid` and its corresponding location.
    pub fn from_data(oid: impl Into<ObjectId>, location: Option<crate::data::entry::Location>) -> Self {
        Count {
            id: oid.into(),
            entry_pack_location: PackLocation::LookedUp(location),
        }

View on GitHub (pinned to e73179060b)