{"record":{"id":"23ef98f18c58a5fc","repo":"GitoxideLabs/gitoxide","slug":"resolution-present-if-id-can-be-used-as-fallback","errorCode":null,"errorMessage":"resolution present if ID can be used as fallback","messagePattern":"resolution present if ID can be used as fallback","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitoxide-core/src/repository/submodule.rs","lineNumber":58,"sourceCode":"        path = sm.path()?,\n        config = if state.superproject_configuration {\n            \"config:yes\"\n        } else {\n            \"config:no\"\n        },\n        head_id = submodule_short_hash(sm.head_id()?, sm_repo.as_ref()),\n        index_id = submodule_short_hash(sm.index_id()?, sm_repo.as_ref()),\n        worktree = match sm_repo {\n            Some(repo) => {\n                // TODO(name-revision): this is the simple version, `git` gives it\n                //                      multiple tries https://github.com/git/git/blob/fac96dfbb1c24369ba7d37a5affd8adfe6c650fd/builtin/submodule--helper.c#L161\n                //                      and even uses `git name-rev`/`git describe --contains` which we can't do yet.\n                repo.head_commit()?\n                    .describe()\n                    .names(SelectRef::AllRefs)\n                    .id_as_fallback(true)\n                    .try_resolve()?\n                    .expect(\"resolution present if ID can be used as fallback\")\n                    .format_with_dirty_suffix(dirty_suffix.map(ToOwned::to_owned))?\n                    .to_string()\n            }\n            None => {\n                \"no worktree\".into()\n            }\n        },\n        url = sm.url()?.to_bstring()\n    )?;\n    Ok(())\n}\n\nfn submodule_short_hash(id: Option<gix::ObjectId>, repo: Option<&Repository>) -> String {\n    id.map_or_else(\n        || \"none\".to_string(),\n        |id| repo.map_or_else(|| id.to_string(), |repo| id.attach(repo).shorten_or_id().to_string()),\n    )\n}","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gitoxide-core/src/repository/submodule.rs#L40-L76","documentation":"When printing submodule info, the head commit ID is used as a fallback to resolve a describe name; `try_resolve()` is expected to succeed whenever an ID is available. The `.expect()` panics if name resolution fails despite a usable head commit ID.","triggerScenarios":"Running submodule listing where a submodule worktree exists with a resolvable head commit, but `repo.head_commit()?.try_resolve()` returns None or resolution otherwise fails.","commonSituations":"Corrupted or shallow submodule repos where the head commit object is missing; detached heads in submodules with broken refs; repositories missing objects after interrupted fetches.","solutions":["Run `git -C <submodule> fsck` / `git fetch` in the submodule to restore missing commit objects.","Initialize/update submodules (`git submodule update --init`) so their HEADs resolve.","Replace the `.expect()` with a graceful fallback (print the raw OID) instead of panicking."],"exampleFix":"// before\n.expect(\"resolution present if ID can be used as fallback\")\n.format_with_dirty_suffix(dirty_suffix.map(ToOwned::to_owned))?\n\n// after\nmatch repo.head_commit()?.try_resolve() {\n    Some(desc) => desc.format_with_dirty_suffix(dirty_suffix.map(ToOwned::to_owned))?.to_string(),\n    None => commit_id.to_string(),\n}","handlingStrategy":"fallback","validationCode":"// verify submodule head resolves before describe\nif repo.head_id().is_err() {\n    return \"no resolvable HEAD\".into();\n}","typeGuard":null,"tryCatchPattern":"match repo.head_commit()?.try_resolve() {\n    Some(desc) => desc.format_with_dirty_suffix(dirty_suffix.map(ToOwned::to_owned))?.to_string(),\n    None => commit_id.to_string(),\n}","preventionTips":["Run `git submodule update --init` before submodule listing","Check submodule object databases are complete (fsck after interrupted fetches)","Fall back to printing the raw OID instead of expecting resolution"],"tags":["git","submodule","panic","describe"],"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-16T04:17:20.429Z"}