GitoxideLabs/gitoxide · error
BUG: tries to obtain object id from symbolic target
Error message
BUG: tries to obtain object id from symbolic target
What it means
`gix_ref::TargetRef::id()` interprets a reference target as an object id and panics with a `BUG:` message if the target is symbolic (points at another ref name). Symbolic targets carry a `FullName`, not an oid, so requesting `.id()` on one is a caller-side logic error, treated as an internal invariant violation.
Solutions
- Match on the target first: only call `.id()` for `TargetRef::Object`
- Use `target.try_id()` (or `try_name()` for symbolic) to handle both variants safely
- Resolve symbolic refs to their peeled target first (e.g. via ref resolution APIs)
- Follow the ref chain until you reach an object target, then take its id
Example fix
// before
let oid = head_target.id(); // panics if HEAD is symbolic
// after
let oid = head_target.try_id().ok_or_else(|| anyhow::anyhow!("HEAD is symbolic, resolve it first"))?; Defensive patterns
Strategy: type-guard
Validate before calling
let oid = match target {
gix_ref::TargetRef::Object(oid) => Some(oid),
gix_ref::TargetRef::Symbolic(_) => None,
}; Type guard
fn peeled(target: &gix_ref::TargetRef<'_>) -> Option<&gix_hash::oid> {
target.try_id()
} Prevention
- Never assume a ref target is peeled; HEAD usually is not
- Use try_id()/try_name() at every target access
- Resolve symbolic refs before oid extraction
When it happens
Trigger: Calling `target.id()` on a `TargetRef::Symbolic(name)` — e.g. on the target of `HEAD` in a freshly cloned repo, which is typically `Symbolic(refs/heads/main)`.
Common situations: Inspecting HEAD's target without unpacking the symbolic chain; reading packed-refs or loose ref entries and assuming they are peeled; iterating refs and calling `.id()` uniformly on all targets.
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
- BUG: expected peeled reference target but found symbolic one
- no item index implies having an object id
- this case should have been removed during processing
- Bug in lookup_symbol_has_path - must return lookup symbols
- this impl is needed to allow passing a known valid partial…
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/77778bee495ba98e.
Report an issue: GitHub.
Appendix: source
Thrown at gix-ref/src/target.rs:25
impl TargetRef<'_> {
/// Returns the kind of the target the ref is pointing to.
pub fn kind(&self) -> Kind {
match self {
TargetRef::Symbolic(_) => Kind::Symbolic,
TargetRef::Object(_) => Kind::Object,
}
}
/// Interpret this target as object id which maybe `None` if it is symbolic.
pub fn try_id(&self) -> Option<&oid> {
match self {
TargetRef::Symbolic(_) => None,
TargetRef::Object(oid) => Some(oid),
}
}
/// Interpret this target as object id or **panic** if it is symbolic.
pub fn id(&self) -> &oid {
match self {
TargetRef::Symbolic(_) => panic!("BUG: tries to obtain object id from symbolic target"),
TargetRef::Object(oid) => oid,
}
}
/// Interpret this target as name of the reference it points to which maybe `None` if it an object id.
pub fn try_name(&self) -> Option<&FullNameRef> {
match self {
TargetRef::Symbolic(name) => Some(name),
TargetRef::Object(_) => None,
}
}
/// Convert this instance into an owned version, without consuming it.
pub fn into_owned(self) -> Target {
self.into()
}
}
impl Target {
/// Returns the kind of the target the ref is pointing to.View on GitHub (pinned to e73179060b)