gitbutlerapp/gitbutler · error

valid hex prefix

Error message

valid hex prefix

What it means

A panic (expect) in but-debug's graph command: each --limit-extension value is parsed with gix::hash::Prefix::from_hex(), and a value containing non-hex characters or a bad length aborts the process with 'valid hex prefix'. Debug-only code path, so input validation is deliberately terse.

Solutions

  1. Pass only hex characters (0-9a-f), e.g. --limit-extension 4c1f0ab.
  2. Get a valid short hash from `git rev-parse --short <ref>` first.
  3. Strip whitespace/ref prefixes before passing the value.

Example fix

# before
but debug graph --limit-extension main

# after
but debug graph --limit-extension $(git rev-parse --short main)
Defensive patterns

Strategy: validation

Validate before calling

# shell: reject non-hex before invoking the CLI
if ! [[ "$EXT" =~ ^[0-9a-fA-F]{4,64}$ ]]; then
  echo "--limit-extension must be 4-64 hex chars" >&2; exit 2
fi

Type guard

function isHexPrefix(s: string): boolean {
  return /^[0-9a-f]{4,64}$/i.test(s);
}

Prevention

When it happens

Trigger: Running `but debug graph --limit-extension <value>` where <value> is not a hex string of 4..=hash-length hex chars — e.g. a branch name, a full ref, or a hash with a typo ('g' instead of 'f').

Common situations: Copy/pasting a branch or ref name where a short hash belongs; trailing whitespace or a 'refs/' prefix in the pasted value; SHA strings from other tools containing non-hex separators.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/e474edc4c7a25e88. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-debug/src/command/graph.rs:64

    let extra_target = graph_args
        .extra_target
        .as_deref()
        .map(|rev_spec| repo.rev_parse_single(rev_spec))
        .transpose()?
        .map(|id| id.detach());
    let opts = but_graph::init::Options {
        extra_target_commit_id: extra_target,
        collect_tags: true,
        hard_limit: graph_args.hard_limit,
        commits_limit_hint: graph_args.limit.flatten(),
        commits_limit_recharge_location: graph_args
            .limit_extension
            .iter()
            .map(|short_hash| {
                repo.objects
                    .lookup_prefix(
                        gix::hash::Prefix::from_hex(short_hash).expect("valid hex prefix"),
                        None,
                    )
                    .unwrap()
                    .expect("object for prefix exists")
                    .expect("the prefix is unambiguous")
            })
            .collect(),
        dangerously_skip_postprocessing_for_debugging: graph_args.no_post,
        worktrees: false,
    };

    let graph = match graph_args.ref_name.as_deref() {
        None => but_graph::Graph::from_head(
            &repo,
            &meta,
            but_core::ref_metadata::ProjectMeta::default(),
            &mut setup::debug_db()?,
            opts,

View on GitHub (pinned to caf1f223d3)