Hmbown/CodeWhale · error

PR diff contains binary metadata without exact full object…

Error message

PR diff contains binary metadata without exact full object IDs; complete local Git objects are required

What it means

Binary files produce no text hunks; the tool instead relies on the `index <old>..<new>` line carrying exact full 40-hex object IDs so the exact binary blobs can be verified against local Git objects. A `Binary files ... differ` line for a file whose preceding `index` line lacked full object IDs (abbreviated hashes) cannot be validated, so the diff is rejected.

Solutions

  1. Re-fetch the diff ensuring full-index output (`git diff --full-index --no-ext-diff base...head`) so binary index lines carry exact 40-hex object IDs
  2. Verify the binary blobs exist locally: `git cat-file -e <full-oid>` for both sides; fetch with `git fetch origin` if objects are missing
  3. Avoid post-processing the diff with tools that abbreviate the index line

Example fix

// before: abbreviated index for binaries
index 8a3f2c1..b9e4d02 100644
// after: full-index output required
index 8a3f2c1a3f2c1a3f2c1a3f2c1a3f2c1a3f2c1a3f..b9e4d02b9e4d02b9e4d02b9e4d02b9e4d02b9e4d02 100644
Defensive patterns

Strategy: validation

Validate before calling

// require full 40-hex ids on index lines before binary sections
let full_index = regex::Regex::new(r"^index [0-9a-f]{40}\.\.[0-9a-f]{40}").unwrap();
for l in diff.lines().filter(|l| l.starts_with("index ")) {
    assert!(full_index.is_match(l), "abbreviated index line: {l}");
}

Type guard

fn has_full_index(index_line: &str) -> bool {
    index_line.split_whitespace().nth(1)
        .map_or(false, |pair| pair.split("..").all(|h| h.len() == 40 && h.chars().all(|c| c.is_ascii_hexdigit())))
}

Try / catch

match diff_with(&view) {
    Err(e) if e.to_string().contains("binary metadata without exact full object IDs") => eprintln!("refetch diff with git diff --full-index"),
    other => other?,
}

Prevention

When it happens

Trigger: `git diff` was invoked without full index output (e.g. missing `--full-index` semantics in the producing command or an abbreviated index line from a rewritten diff) and the diff contains binary files.

Common situations: Diff text produced by `gh pr diff` or a wrapper that abbreviates index lines; diffs copied through tools that shorten SHAs; a repository whose diff pipeline was configured with core.abbrev or custom formatting; PRs that add images or other binary assets.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/a01b238ab81b1913. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/review_pr.rs:224

            has_patch = true;
        } else if line.starts_with("@@") {
            bail!("Incomplete PR diff: malformed hunk header");
        } else if [
            "new file mode ",
            "deleted file mode ",
            "old mode ",
            "new mode ",
            "rename from ",
            "rename to ",
            "GIT binary patch",
        ]
        .iter()
        .any(|prefix| line.starts_with(prefix))
        {
            has_patch = true;
        } else if line.starts_with("Binary files ") {
            if !has_full_index {
                bail!(
                    "PR diff contains binary metadata without exact full object IDs; complete local Git objects are required"
                );
            }
            has_patch = true;
        }
    }
    if remaining != (0, 0)
        || !has_patch
        || files == 0
        || files != view.changed_files
        || additions != view.additions
        || deletions != view.deletions
    {
        bail!(
            "Incomplete PR diff: received {files} file patches, {additions} additions and {deletions} deletions; expected {}, {} and {}. No partial review is accepted.",
            view.changed_files,
            view.additions,
            view.deletions

View on GitHub (pinned to 73e0f67d83)