GitoxideLabs/gitoxide · warning · anyhow::Error

Explanations are only for human consumption

Error message

Explanations are only for human consumption

What it means

`gix revision resolve` supports pretty-printed JSON output, but the optional per-spec 'explanation' feature only works in human output, so requesting `--format json` together with explanation (`--explain`) bails. Explanations have no JSON representation implemented, making this a mutually-exclusive-options guard.

Solutions

  1. Drop `--format json` when using `--explain` (explanations are human-only)
  2. Drop `--explain` when JSON output is needed
  3. Run two invocations: one human with --explain for insight, one JSON without it for scripts
  4. Request JSON explanation support upstream

Example fix

// before
gix revision resolve --explain --format json HEAD main
// after
gix revision resolve --format json HEAD main
Defensive patterns

Strategy: validation

Validate before calling

# refuse the invalid combination before invoking
if [ "$explain" = "1" ] && [ "$fmt" = "json" ]; then
  echo "--explain cannot be combined with --format json" >&2; exit 2
fi

Try / catch

if ! out=$(gix revision resolve --explain --format json HEAD 2>&1); then
  case "$out" in *"only for human consumption") gix revision resolve --format json HEAD;; esac
fi

Prevention

When it happens

Trigger: Calling `gix revision resolve --explain --format json` (resolve in gitoxide-core/src/repository/revision/resolve.rs, serde feature enabled): `OutputFormat::Json` combined with `explain == true`.

Common situations: Users wanting machine-readable explanations of how specs resolve; scripts piping resolve output to jq while also enabling --explain for debugging.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/1ba6902200ffec87. Report an issue: GitHub.

Appendix: source

Thrown at gitoxide-core/src/repository/revision/resolve.rs:88

                    }
                    let spec = gix::path::os_str_into_bstr(&spec)?;
                    let spec = repo.rev_parse(spec)?;
                    if cat_file {
                        return display_object(&repo, spec, tree_mode, cache.as_mut().map(|c| (blob_format, c)), out);
                    }
                    if let Some(r) = spec.first_reference().filter(|_| show_reference) {
                        writeln!(out, "{}", r.name)?;
                    }
                    if let Some(r) = spec.second_reference().filter(|_| show_reference) {
                        writeln!(out, "{}", r.name)?;
                    }
                    writeln!(out, "{spec}", spec = spec.detach())?;
                }
            }
            #[cfg(feature = "serde")]
            OutputFormat::Json => {
                if explain {
                    anyhow::bail!("Explanations are only for human consumption")
                }
                serde_json::to_writer_pretty(
                    &mut out,
                    &specs
                        .into_iter()
                        .map(|spec| {
                            gix::path::os_str_into_bstr(&spec)
                                .map_err(anyhow::Error::from)
                                .and_then(|spec| repo.rev_parse(spec).map_err(Into::into))
                                .map(gix::revision::Spec::detach)
                        })
                        .collect::<Result<Vec<_>, _>>()?,
                )?;
            }
        }
        Ok(())
    }
}

View on GitHub (pinned to e73179060b)