{"record":{"id":"3cffce6cccf929cc","repo":"GitoxideLabs/gitoxide","slug":"a-parent-is-always-there-unless-empty","errorCode":null,"errorMessage":"a parent is always there unless empty","messagePattern":"a parent is always there unless empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"gix-ref/src/store/file/overlay_iter.rs","lineNumber":329,"sourceCode":"            } => SortedLoosePaths::at(base, base.into(), None, Some(\"HEAD\".into()), precompose_unicode),\n        }\n        .peekable()\n    }\n\n    fn from_prefix(base: &'a Path, prefix: &'a RelativePath, precompose_unicode: bool) -> std::io::Result<Self> {\n        let prefix_path = gix_path::from_bstr(prefix.as_ref().as_bstr());\n        let iter_root = base.join(&prefix_path);\n        if prefix.as_ref().ends_with(b\"/\") {\n            Ok(IterInfo::BaseAndIterRoot {\n                base,\n                iter_root,\n                prefix: prefix_path.into_owned(),\n                precompose_unicode,\n            })\n        } else {\n            let iter_root = iter_root\n                .parent()\n                .expect(\"a parent is always there unless empty\")\n                .to_owned();\n            Ok(IterInfo::ComputedIterationRoot {\n                base,\n                prefix: prefix.as_ref().as_bstr().into(),\n                iter_root,\n                precompose_unicode,\n            })\n        }\n    }\n}\n\nimpl file::Store {\n    /// Return an iterator over all references, loose or `packed`, sorted by their name.\n    ///\n    /// Errors are returned similarly to what would happen when loose and packed refs were iterated by themselves.\n    pub fn iter_packed<'s, 'p>(\n        &'s self,\n        packed: Option<&'p packed::Buffer>,","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-ref/src/store/file/overlay_iter.rs#L311-L347","documentation":"`IterInfo::from_prefix` computes the iteration root for a prefix search; when the computed root has a prefix, it takes `iter_root.parent()`. The `expect(\"a parent is always there unless empty\")` asserts that any non-empty path has a parent component. A panic means the derived iteration root was empty or a bare root with no parent where one was required.","triggerScenarios":"Calling prefix-scoped reference iteration (e.g. `store.iter(prefix)` / listing refs under a prefix) where the root path derivation yields a path with no parent — internal path-derivation bug or a degenerate/unusual git-dir path.","commonSituations":"Unusual git-dir locations (e.g. git-dir at filesystem root `/`), heavily customized or symlinked layouts, or a gix-ref bug in root normalization. Ordinary `repo.references()?.iter_prefix(...)` calls never hit it.","solutions":["Check where the repository's git-dir/common-dir actually reside; avoid pathological roots like `/`","Verify environment overrides (`GIT_DIR`, `GIT_COMMON_DIR`) aren't pointing at a bare root","Simplify the layout (normal clone location) and retry the prefix iteration","If it reproduces on a standard repo, report a gix-ref bug with the exact prefix and layout"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check the derived root is a usable directory before prefix iteration\nfn root_ok(git_dir: &std::path::Path) -> bool { git_dir.parent().is_some() && git_dir.is_dir() }","typeGuard":null,"tryCatchPattern":"// Panic path; validate layout up front instead of catching\nif !root_ok(git_dir) { return Err(\"unusable git-dir location\"); }","preventionTips":["Avoid pathological git-dir locations such as the filesystem root","Audit `GIT_DIR`/`GIT_COMMON_DIR` overrides before running prefix iteration","Use standard clone layouts in CI and production","Report reproducible panics with the exact prefix and repository paths"],"tags":["rust","panic","gix-ref","path-handling","prefix-iteration"],"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"}