{"record":{"id":"093e545c19c63d04","repo":"GitoxideLabs/gitoxide","slug":"bug-tries-to-obtain-object-id-from-symbolic-targe-093e54","errorCode":null,"errorMessage":"BUG: tries to obtain object id from symbolic target","messagePattern":"BUG: tries to obtain object id from symbolic target","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix/src/reference/mod.rs","lineNumber":37,"sourceCode":"pub mod log;\n\nmod edits;\npub use edits::{delete, set_target_id};\n\n/// Access\nimpl<'repo> Reference<'repo> {\n    /// Returns the attached id we point to, or `None` if this is a symbolic ref.\n    pub fn try_id(&self) -> Option<Id<'repo>> {\n        match self.inner.target {\n            gix_ref::Target::Symbolic(_) => None,\n            gix_ref::Target::Object(oid) => oid.to_owned().attach(self.repo).into(),\n        }\n    }\n\n    /// Returns the attached id we point to, or panic if this is a symbolic ref.\n    pub fn id(&self) -> Id<'repo> {\n        self.try_id()\n            .expect(\"BUG: tries to obtain object id from symbolic target\")\n    }\n\n    /// Return the target to which this reference points to.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {\n    /// # mod doctest { include!(concat!(env!(\"CARGO_MANIFEST_DIR\"), \"/tests/doctest.rs\")); }\n    /// # let repo = doctest::open_repo(doctest::basic_repo_dir()?)?;\n    /// let branch = repo.find_reference(\"main\")?;\n    ///\n    /// assert_eq!(branch.target().try_id().expect(\"direct target\"), repo.head_id()?.as_ref());\n    /// # Ok(()) }\n    /// ```\n    pub fn target(&self) -> gix_ref::TargetRef<'_> {\n        self.inner.target.to_ref()\n    }","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix/src/reference/mod.rs#L19-L55","documentation":"`Reference::id()` on a `gix::Reference` panics with this message when the reference is symbolic (points at another ref, e.g. HEAD -> refs/heads/main) rather than directly at an object. The library deliberately panics because the caller asked for an object id that a symbolic target cannot provide. The non-panicking counterpart `try_id()` returns `None` instead.","triggerScenarios":"Calling `.id()` on a `Reference` obtained from e.g. `repo.head().into_reference()` or `repo.find_reference(...)` when that reference is symbolic, most commonly HEAD before any commit exists (unborn HEAD) or a detached-state check skipped.","commonSituations":"Reading HEAD on a freshly `git init`-ed repository where HEAD points to a yet-unborn branch; iterating refs and assuming all are direct; code ported from git2 that used `resolve()` implicitly.","solutions":["Check the reference kind first and only call `id()` on direct refs: use `reference.try_id()` and handle `None`.","If the ref is symbolic, call `.into_fully_peeled_id()` (or follow the symbolic chain) to resolve to the final object id.","For HEAD specifically, use `repo.head()` / `repo.head_id()` / `repo.head_commit()` which handle symbolic and unborn states."],"exampleFix":"// before\nlet id = reference.id();\n// after\nlet id = match reference.try_id() {\n    Some(id) => id,\n    None => reference.into_fully_peeled_id()?, // symbolic: peel to object\n};","handlingStrategy":"type-guard","validationCode":"if reference.try_id().is_none() {\n    // symbolic ref: resolve or handle\n}\n","typeGuard":"fn is_direct(r: &gix::Reference<'_>) -> bool { r.try_id().is_some() }\n","tryCatchPattern":null,"preventionTips":["Prefer try_id()/into_fully_peeled_id() over id() unless kind is verified","Remember HEAD is symbolic until detached; use repo.head_id()","Check reference.kind() (Symbolic vs Packed/Direct) before unwrapping"],"tags":["panic","reference","symbolic-ref","git"],"backgroundTag":"null-argument","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"}