{"record":{"id":"a01b238ab81b1913","repo":"Hmbown/CodeWhale","slug":"pr-diff-contains-binary-metadata-without-exact-full-object","errorCode":null,"errorMessage":"PR diff contains binary metadata without exact full object IDs; complete local Git objects are required","messagePattern":"PR diff contains binary metadata without exact full object IDs; complete local Git objects are required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/review_pr.rs","lineNumber":224,"sourceCode":"            has_patch = true;\n        } else if line.starts_with(\"@@\") {\n            bail!(\"Incomplete PR diff: malformed hunk header\");\n        } else if [\n            \"new file mode \",\n            \"deleted file mode \",\n            \"old mode \",\n            \"new mode \",\n            \"rename from \",\n            \"rename to \",\n            \"GIT binary patch\",\n        ]\n        .iter()\n        .any(|prefix| line.starts_with(prefix))\n        {\n            has_patch = true;\n        } else if line.starts_with(\"Binary files \") {\n            if !has_full_index {\n                bail!(\n                    \"PR diff contains binary metadata without exact full object IDs; complete local Git objects are required\"\n                );\n            }\n            has_patch = true;\n        }\n    }\n    if remaining != (0, 0)\n        || !has_patch\n        || files == 0\n        || files != view.changed_files\n        || additions != view.additions\n        || deletions != view.deletions\n    {\n        bail!(\n            \"Incomplete PR diff: received {files} file patches, {additions} additions and {deletions} deletions; expected {}, {} and {}. No partial review is accepted.\",\n            view.changed_files,\n            view.additions,\n            view.deletions","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/review_pr.rs#L206-L242","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["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","Verify the binary blobs exist locally: `git cat-file -e <full-oid>` for both sides; fetch with `git fetch origin` if objects are missing","Avoid post-processing the diff with tools that abbreviate the index line"],"exampleFix":"// before: abbreviated index for binaries\nindex 8a3f2c1..b9e4d02 100644\n// after: full-index output required\nindex 8a3f2c1a3f2c1a3f2c1a3f2c1a3f2c1a3f2c1a3f..b9e4d02b9e4d02b9e4d02b9e4d02b9e4d02b9e4d02 100644","handlingStrategy":"validation","validationCode":"// require full 40-hex ids on index lines before binary sections\nlet full_index = regex::Regex::new(r\"^index [0-9a-f]{40}\\.\\.[0-9a-f]{40}\").unwrap();\nfor l in diff.lines().filter(|l| l.starts_with(\"index \")) {\n    assert!(full_index.is_match(l), \"abbreviated index line: {l}\");\n}","typeGuard":"fn has_full_index(index_line: &str) -> bool {\n    index_line.split_whitespace().nth(1)\n        .map_or(false, |pair| pair.split(\"..\").all(|h| h.len() == 40 && h.chars().all(|c| c.is_ascii_hexdigit())))\n}","tryCatchPattern":"match diff_with(&view) {\n    Err(e) if e.to_string().contains(\"binary metadata without exact full object IDs\") => eprintln!(\"refetch diff with git diff --full-index\"),\n    other => other?,\n}","preventionTips":["Always produce the review diff with --full-index","Ensure binary objects are fetched locally (`git fetch origin`) so full oids resolve","Avoid tools that abbreviate SHAs when transporting diffs"],"tags":["git","binary-files","diff","data-integrity"],"backgroundTag":"missing-dependency","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}