{"record":{"id":"e7a16ce0d705c720","repo":"GitoxideLabs/gitoxide","slug":"err-re-raised-revision-spec-parse-error-via-bai","errorCode":null,"errorMessage":"{err} (re-raised revision-spec parse error via bail!(err))","messagePattern":"(.+?) \\(re-raised revision-spec parse error via bail!\\(err\\)\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"gitoxide-core/src/repository/revision/explain.rs","lineNumber":19,"sourceCode":"use anyhow::bail;\nuse gix::{\n    Exn,\n    bstr::{BStr, BString},\n    revision::plumbing::{\n        spec,\n        spec::parse::{\n            Delegate, delegate,\n            delegate::{PeelTo, ReflogLookup, SiblingBranch, Traversal},\n        },\n    },\n};\n\npub fn explain(spec: std::ffi::OsString, mut out: impl std::io::Write) -> anyhow::Result<()> {\n    let mut explain = Explain::new(&mut out);\n    let spec = gix::path::os_str_into_bstr(&spec)?;\n    gix::revision::plumbing::spec::parse(spec, &mut explain).map_err(gix::Error::from)?;\n    if let Some(err) = explain.err {\n        bail!(err);\n    }\n    Ok(())\n}\n\nstruct Explain<'a> {\n    out: &'a mut dyn std::io::Write,\n    call: usize,\n    ref_name: Option<BString>,\n    oid_prefix: Option<gix::hash::Prefix>,\n    has_implicit_anchor: bool,\n    err: Option<String>,\n}\n\nimpl<'a> Explain<'a> {\n    fn new(out: &'a mut impl std::io::Write) -> Self {\n        Explain {\n            out,\n            call: 0,","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gitoxide-core/src/repository/revision/explain.rs#L1-L37","documentation":"`explain` runs a revision-spec parse while collecting explanation callbacks; if the parser recorded an error via the `Explain` visitor, that error is re-raised with `bail!(err)`. The message text shown to users is the underlying gix revision-spec parse error (e.g. 'unknown revision or path not in the working tree'-style diagnostics), surfaced through anyhow. The comment placeholder `{err}` stands for the actual spec error text.","triggerScenarios":"Calling `gix explain <spec>` (gitoxide-core/src/repository/revision/explain.rs::explain) with a revision expression that gix's `gix::revision::plumbing::spec::parse` cannot resolve: bad `~`/`^` selectors, nonexistent ref names, invalid `@{...}` expressions, or malformed range syntax.","commonSituations":"Typos in branch/tag names, using ranges or `^N` parent selectors on objects that don't support them, ambiguous short hashes, or specs referencing objects missing from a shallow/partial clone.","solutions":["Fix the revision expression; verify the ref/commit exists with `git rev-parse <spec>`","Check for typos and ambiguity in short object IDs","Ensure the needed objects are present (unshallow shallow clones)","Use `gix revision parse` or run the same spec against git to compare diagnostics"],"exampleFix":"// before\ngix explain HEAD~^@\n// after\ngix explain HEAD~1","handlingStrategy":"validation","validationCode":"# resolve the spec with git first to validate\nif git rev-parse --verify --quiet \"$spec\"^{commit} >/dev/null; then\n  gix explain \"$spec\"\nfi","typeGuard":null,"tryCatchPattern":"match gix_explain_result {\n    Err(e) if e.to_string().contains(\"did not match\") => eprintln!(\"invalid revision spec: {spec}\"),\n    Err(e) => return Err(e),\n    Ok(_) => {}\n}","preventionTips":["Validate revision expressions with `git rev-parse` before explaining them","Avoid exotic selectors (^N, @{...}) unless sure the objects exist","Unshallow shallow clones before traversing historic revisions","Test specs interactively before embedding them in scripts"],"tags":["cli","git","revision-spec","parsing"],"backgroundTag":"invalid-argument-format","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"}