{"record":{"id":"8c872644278f6566","repo":"GitoxideLabs/gitoxide","slug":"must-have-been-resolved","errorCode":null,"errorMessage":"must have been resolved","messagePattern":"must have been resolved","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-pack/src/data/output/count/mod.rs","lineNumber":20,"sourceCode":"\nuse crate::data::output::Count;\n\n/// Specifies how the pack location was handled during counting\n#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub enum PackLocation {\n    /// We did not lookup this object\n    NotLookedUp,\n    /// The object was looked up and there may be a location in a pack, along with entry information\n    LookedUp(Option<crate::data::entry::Location>),\n}\n\nimpl PackLocation {\n    /// Directly go through to `LookedUp` variant, panic otherwise\n    pub fn is_none(&self) -> bool {\n        match self {\n            PackLocation::LookedUp(opt) => opt.is_none(),\n            PackLocation::NotLookedUp => unreachable!(\"must have been resolved\"),\n        }\n    }\n    /// Directly go through to `LookedUp` variant, panic otherwise\n    pub fn as_ref(&self) -> Option<&crate::data::entry::Location> {\n        match self {\n            PackLocation::LookedUp(opt) => opt.as_ref(),\n            PackLocation::NotLookedUp => unreachable!(\"must have been resolved\"),\n        }\n    }\n}\n\nimpl Count {\n    /// Create a new instance from the given `oid` and its corresponding location.\n    pub fn from_data(oid: impl Into<ObjectId>, location: Option<crate::data::entry::Location>) -> Self {\n        Count {\n            id: oid.into(),\n            entry_pack_location: PackLocation::LookedUp(location),\n        }","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-pack/src/data/output/count/mod.rs#L2-L38","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Resolve counts first: run the pack-entry location resolution (e.g. `gix_pack::data::output::count::iter...]` with lookup enabled) before calling `is_none()`.","Use a `match` on the `PackLocation` enum to handle `NotLookedUp` explicitly instead of `is_none()`.","If locations are intentionally not needed, don't query them — configure the output so lookup is performed only when you consume locations."],"exampleFix":"// before\nif count.entry_pack_location.is_none() { ... }\n// after\nmatch &count.entry_pack_location {\n    PackLocation::LookedUp(opt) => { /* use opt */ }\n    PackLocation::NotLookedUp => { /* resolve locations first */ }\n}","handlingStrategy":"type-guard","validationCode":"// Only call is_none() after verifying resolution state\nfn locations_resolved(loc: &gix_pack::data::output::count::PackLocation) -> bool {\n    matches!(loc, gix_pack::data::output::count::PackLocation::LookedUp(_))\n}","typeGuard":"fn as_looked_up(loc: &PackLocation) -> Option<&Option<crate::data::entry::Location>> {\n    match loc {\n        PackLocation::LookedUp(opt) => Some(opt),\n        PackLocation::NotLookedUp => None,\n    }\n}","tryCatchPattern":null,"preventionTips":["Always run the pack-location resolution phase before inspecting count locations.","Prefer exhaustive `match` over convenience accessors like `is_none()`/`as_ref()`.","Enable lookup in output options whenever your code consumes locations."],"tags":["panic","pack","unresolved-state","internal-invariant","rust"],"backgroundTag":"invalid-state-transition","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"}