GitoxideLabs/gitoxide · warning
valid ref
Error message
valid ref
What it means
This is a Rust `expect()` panic inside `FullNameRef::file_name()` in gix-ref. The method splits the full ref name on `/` with `rsplitn(2, ...)` and takes the last segment; the `expect("valid ref")` asserts that `rsplitn` always yields at least one piece. Since `rsplitn` on any (even empty) byte string always returns at least one item, this panic fires only if the underlying `BStr` invariant of a `FullNameRef` was broken (e.g. the struct was constructed from a null/empty name via `new_unchecked` on garbage memory or via unsafe/FFI paths).
Solutions
- Construct ref names only through validating APIs (`FullName::try_from`, `gix_ref::fullname::FullName::try_from(...)`) rather than `new_unchecked`.
- Verify the name bytes are non-empty and contain no leading/trailing `/` before wrapping them as a `FullName`.
- If you control input, sanitize it with the same rules git uses (see `gix_ref::validate::prelude` helpers) before conversion.
- If the panic occurs on names produced by the library itself, report it upstream with the exact ref name bytes; it is an internal invariant violation.
Example fix
// before
let name = unsafe { FullNameRef::new_unchecked(BStr::new(&raw_bytes)) };
let file = name.file_name(); // may panic
// after
let name = FullName::try_from(raw_bytes.as_bstr())?; // validates
let file = name.as_ref().file_name(); Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_fullname(name: &gix_ref::FullNameRef) -> bool {
!name.as_bstr().is_empty()
}
// use validating constructor before calling file_name()
let name = gix_ref::FullName::try_from(bytes.as_bstr())?; Type guard
fn file_name_safe(name: &gix_ref::FullNameRef) -> Option<&bstr::BStr> {
if name.as_bstr().is_empty() { None } else { Some(name.file_name()) }
} Prevention
- Only create FullName/FullNameRef via try_from-style validating constructors
- Never use new_unchecked on untrusted bytes
- Sanitize ref names from external sources before wrapping them
When it happens
Trigger: Calling `FullNameRef::file_name()` on a `FullNameRef` whose inner bytes were constructed outside the library's validation (e.g. `FullName::try_from` was bypassed with `new_unchecked` on an empty or non-UTF8-safe buffer, or a ref name was hand-crafted from raw bytes read from disk).
Common situations: Users building `gix_ref::FullName` from raw bytes of their own ref-storage format; FFI/unsafe code reinterpreting a `FullNameRef`; corrupted ref files fed through low-level APIs instead of the validating constructors.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- ' ' is not a valid configuration key
- Cannot use iter_v1() on index of type
- Cannot use iter_v2() on index of type
- BUG: tries to obtain object id from symbolic target
- BUG: expected peeled reference target but found symbolic one
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/426bb8045df3369f.
Report an issue: GitHub.
Appendix: source
Thrown at gix-ref/src/fullname.rs:255
}
/// Classify this name, or return `None` if it's unclassified.
pub fn category(&self) -> Option<crate::Category<'_>> {
self.as_ref().category()
}
/// Classify this name, or return `None` if it's unclassified. If `Some`,
/// the shortened name is returned as well.
pub fn category_and_short_name(&self) -> Option<(crate::Category<'_>, &BStr)> {
self.as_ref().category_and_short_name()
}
}
impl FullNameRef {
/// Return the file name portion of a full name, for instance `main` if the
/// full name was `refs/heads/main`.
pub fn file_name(&self) -> &BStr {
self.0.rsplitn(2, |b| *b == b'/').next().expect("valid ref").as_bstr()
}
}
impl Borrow<FullNameRef> for FullName {
#[inline]
fn borrow(&self) -> &FullNameRef {
FullNameRef::new_unchecked(self.0.as_bstr())
}
}
impl AsRef<FullNameRef> for FullName {
fn as_ref(&self) -> &FullNameRef {
self.borrow()
}
}
impl ToOwned for FullNameRef {
type Owned = FullName;View on GitHub (pinned to e73179060b)