{"record":{"id":"9509dda2b4e142cc","repo":"GitoxideLabs/gitoxide","slug":"prior-peek","errorCode":null,"errorMessage":"prior peek","messagePattern":"prior peek","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"gix-ref/src/store/file/overlay_iter.rs","lineNumber":165,"sourceCode":"                            Ordering::Greater => Some((r_cd, IterKind::Common)),\n                        }\n                    }\n                },\n                None => git_dir.peek().map(|r| (r, IterKind::Git)),\n            }\n        }\n        match self.iter_packed.as_mut() {\n            Some(packed_iter) => match (\n                peek_loose(&mut self.iter_git_dir, self.iter_common_dir.as_mut()),\n                packed_iter.peek(),\n            ) {\n                (None, None) => None,\n                (None, Some(_)) | (Some(_), Some(Err(_))) => {\n                    let res = packed_iter.next().expect(\"peeked value exists\");\n                    Some(self.convert_packed(res))\n                }\n                (Some((_, kind)), None) | (Some((Err(_), kind)), Some(_)) => {\n                    let res = self.loose_iter(kind).next().expect(\"prior peek\");\n                    Some(self.convert_loose(res))\n                }\n                (Some((Ok((_, loose_name)), kind)), Some(Ok(packed))) => match loose_name.as_ref().cmp(packed.name) {\n                    Ordering::Less => {\n                        let res = self.loose_iter(kind).next().expect(\"prior peek\");\n                        Some(self.convert_loose(res))\n                    }\n                    Ordering::Equal => {\n                        drop(packed_iter.next());\n                        let res = self.loose_iter(kind).next().expect(\"prior peek\");\n                        Some(self.convert_loose(res))\n                    }\n                    Ordering::Greater => {\n                        let res = packed_iter.next().expect(\"name retrieval configured\");\n                        Some(self.convert_packed(res))\n                    }\n                },\n            },","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-ref/src/store/file/overlay_iter.rs#L147-L183","documentation":"Same `next()` merge logic: after `peek_loose` returned `Some`, the loose iterator's `next()` must also return `Some`; `expect(\"prior peek\")` enforces that the previously peeked loose entry still exists. A panic means peek and next disagreed for the loose iterator (git-dir or common-dir).","triggerScenarios":"Enumerating loose refs where `peek_loose` observed an entry but the inner `loose_iter(kind).next()` then returned `None` — caused by concurrent deletion of loose ref files between peek and next, or a broken iterator.","commonSituations":"Most plausible real-world cause is another process (e.g. `git gc`, a concurrent ref update) deleting the loose ref while the iteration was in progress; otherwise a gix-ref bug.","solutions":["Avoid mutating refs (or running gc) concurrently with reference iteration, or hold appropriate locking","Re-run the iteration; a one-off race resolves itself","Check for background processes touching `.git/refs` during the operation","If reproducible without concurrency, report a gix-ref bug"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Retry the whole iteration on panic, assuming a transient race\nlet refs = (0..3).find_map(|_| std::panic::catch_unwind(|| store.iter().collect::<Vec<_>>()).ok());","preventionTips":["Don't run gc/ref-deletion concurrently with ref iteration","Serialize ref access with locking in multi-process tooling","Detect ref-database churn (mtimes under refs/) and retry","Report single-threaded reproductions as gix-ref bugs"],"tags":["rust","panic","gix-ref","loose-ref","race-condition","iterator"],"backgroundTag":"internal-invariant-violation","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"}