gitbutlerapp/gitbutler · error

object for prefix exists

Error message

object for prefix exists

What it means

Panic in 'but debug graph' when a --limit-extension value parses as valid hex but repo.objects.lookup_prefix finds no object whose id starts with that prefix (returns Ok(None)). The command assumes every well-formed prefix resolves locally and expects an object unconditionally; a matching-but-ambiguous prefix instead panics on the neighboring 'the prefix is unambiguous' expect.

Source

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

        .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,
        worktree_tips: vec![],
    };

    let graph = match graph_args.ref_name.as_deref() {
        None => but_graph::Graph::from_head(
            &repo,
            &meta,
            but_core::ref_metadata::ProjectMeta::default(),
            opts,
        ),
        Some(ref_name) => {
            let mut reference = repo.find_reference(ref_name)?;
            let id = reference.peel_to_id()?;
            but_graph::Graph::from_commit_traversal(

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Verify the prefix resolves locally: 'git cat-file -t <prefix>' or 'git rev-parse --verify <prefix>^0'
  2. Fetch the missing history first ('git fetch --all' or fetch the specific ref) and re-run
  3. Use the full 40-char id to rule out typos and ambiguity
  4. Maintainer: convert the unwrap/expect chain into an error naming the prefix

Example fix

// before
repo.objects.lookup_prefix(prefix, None).unwrap().expect("object for prefix exists")

// after
let Some(id) = repo.objects.lookup_prefix(prefix, None).map_err(anyhow::Error::from)? else {
    anyhow::bail!("no object in this repository starts with prefix {short_hash}");
};
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the prefix resolves before invoking the debug graph
let output = std::process::Command::new("git")
    .args(["cat-file", "-t", short_hash])
    .output()?;
if !output.status.success() {
    anyhow::bail!("no object '{short_hash}' in this clone; git fetch first");
}

Prevention

When it happens

Trigger: Passing an abbreviated hash from a different clone or repository; a commit that exists only on an unfetched remote; an object pruned by garbage collection; a valid-hex typo that matches nothing in the ODB.

Common situations: Copying short SHAs from a PR web page into a clone that never fetched that ref; shallow or partial clones missing the commit; prefix computed against a SHA-256 repo while the local repo is SHA-1.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/b653560c029083f9. Report an issue: GitHub.