{"record":{"id":"e6b7246df6121a02","repo":"Hmbown/CodeWhale","slug":"review-receipt-check-failed","errorCode":null,"errorMessage":"Review receipt check failed: {}","messagePattern":"Review receipt check failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":8094,"sourceCode":"    };\n    let validation =\n        crate::tools::review::validate_review_receipt_for_diff(diff, &receipt, Some(path.clone()));\n\n    if args.json {\n        println!(\n            \"{}\",\n            serde_json::to_string_pretty(&serde_json::json!({\n                \"mode\": \"review_receipt_check\",\n                \"success\": validation.passed,\n                \"validation\": review_receipt_validation_public_json(&validation),\n            }))?\n        );\n    } else if validation.passed {\n        println!(\"Review receipt valid: {}\", path.display());\n    }\n\n    if !validation.passed {\n        bail!(\"Review receipt check failed: {}\", validation.reason);\n    }\n    Ok(())\n}\n\nfn review_receipt_validation_public_json(\n    validation: &crate::tools::review::ReviewReceiptValidation,\n) -> serde_json::Value {\n    let unresolved_risk = validation.unresolved_risk.as_ref();\n    serde_json::json!({\n        \"passed\": validation.passed,\n        \"status\": review_receipt_validation_status(validation),\n        \"diff_fingerprint\": validation.diff_fingerprint.as_str(),\n        \"receipt_fingerprint\": validation.receipt_fingerprint.as_deref(),\n        \"unresolved\": unresolved_risk.is_some_and(|risk| risk.unresolved),\n        \"risk_level\": unresolved_risk.map(|risk| risk.level.as_str()),\n    })\n}\n","sourceCodeStart":8076,"sourceCodeEnd":8112,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/lib.rs#L8076-L8112","documentation":"After a `--check-receipt` run, run_review_receipt_check() inspects the ReviewReceiptValidation and bails with its reason when validation.passed is false. The validator produces three concrete reasons: an unsupported receipt schema version, \"current diff fingerprint does not match receipt\" (the diff text changed since the receipt was written), or an unresolved risk recorded on the receipt (its summary becomes the reason).","triggerScenarios":"Checking a receipt whose diff_fingerprint differs from the currently collected diff (any edit, rebase, or a different --staged/--base/--path selection than the writing run); a receipt from an older schema version; a receipt whose review recorded unresolved_risk.","commonSituations":"Editing code between the review that wrote the receipt and the check; rebasing; CI enforcing receipts on merges; regenerating receipts across codewhale versions.","solutions":["Re-run the review with `--write-receipt` against the exact current diff, then `--check-receipt` again","Ensure the check uses the identical diff selection (--staged/--base/--path) as the write","If the reason is unresolved risk, address the review findings before re-reviewing","For schema-version reasons, regenerate the receipt with the current codewhale version"],"exampleFix":"// before: diff changed since the receipt was written\n$ codewhale review --check-receipt --receipt-path r.json\nError: Review receipt check failed: current diff fingerprint does not match receipt\n\n// after: re-review the exact current diff, then check\n$ codewhale review --write-receipt --receipt-path r.json\n$ codewhale review --check-receipt --receipt-path r.json","handlingStrategy":"try-catch","validationCode":"# the fingerprint covers the diff text; detect drift before checking\nnow=$(git diff | sha256sum)\n[ \"$now\" = \"$AT_WRITE_TIME\" ] || echo 'diff changed since receipt write'","typeGuard":null,"tryCatchPattern":"codewhale review --check-receipt --receipt-path r.json || {\n  echo 'receipt no longer matches the diff; re-run --write-receipt' >&2; exit 1\n}","preventionTips":["Treat any diff mutation between write and check as invalidating the receipt","Pin --staged/--base/--path identically in both steps","Read the emitted JSON validation block for the machine-readable reason before acting"],"tags":["review","receipt","integrity","fingerprint"],"backgroundTag":"integrity-check-failed","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}