{"record":{"id":"1002e64ad3b1b748","repo":"Hmbown/CodeWhale","slug":"estimated-retained-payload-bytes-is-smaller-than-the-frozen","errorCode":null,"errorMessage":"estimated_retained_payload_bytes is smaller than the frozen retained content","messagePattern":"estimated_retained_payload_bytes is smaller than the frozen retained content","errorType":"validation","errorClass":"PersistenceBacklogError","httpStatus":null,"severity":"error","filePath":"scripts/check-persistence-backlog-budget.py","lineNumber":202,"sourceCode":"    accepted = non_negative_integer(receipt[\"accepted_requests\"], \"accepted_requests\")\n    if accepted != attempted:\n        raise PersistenceBacklogError(\n            \"accepted_requests must equal requests_attempted; sender rejection is not backlog improvement\"\n        )\n    retained = non_negative_integer(\n        receipt[\"retained_queued_requests\"], \"retained_queued_requests\"\n    )\n    if retained > accepted:\n        raise PersistenceBacklogError(\"retained_queued_requests exceeds accepted_requests\")\n    for field in (\"estimated_retained_payload_bytes\", \"enqueue_elapsed_ns\"):\n        non_negative_integer(receipt[field], field)\n    if retained == 0 or receipt[\"estimated_retained_payload_bytes\"] == 0:\n        raise PersistenceBacklogError(\n            \"the paused channel must retain the newest request and its payload\"\n        )\n    minimum_payload_bytes = retained * FIXTURE[\"content_bytes_per_request\"]\n    if receipt[\"estimated_retained_payload_bytes\"] < minimum_payload_bytes:\n        raise PersistenceBacklogError(\n            \"estimated_retained_payload_bytes is smaller than the frozen retained content\"\n        )\n    applied = non_negative_integer(\n        receipt[\"applied_version\"], \"applied_version\"\n    )\n    if applied != FIXTURE[\"expected_applied_version\"]:\n        raise PersistenceBacklogError(\"applied_version is not the final sent version\")\n    if receipt[\"final_version_applied\"] is not True:\n        raise PersistenceBacklogError(\"final_version_applied must be true\")\n\n    limitations = receipt[\"limitations\"]\n    if not isinstance(limitations, list) or not limitations or not all(\n        isinstance(item, str) and item for item in limitations\n    ):\n        raise PersistenceBacklogError(\"limitations must be a non-empty string array\")\n\n    if not isinstance(receipt[\"rss_supported\"], bool):\n        raise PersistenceBacklogError(\"rss_supported must be boolean\")","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-persistence-backlog-budget.py#L184-L220","documentation":"estimated_retained_payload_bytes must be at least retained_queued_requests * 65536 (the frozen content_bytes_per_request). The payload estimate is a floor, not a guess: each retained request carries at least its frozen 64 KiB content, so a smaller estimate means the estimator undercounts the retained backlog.","triggerScenarios":"Raised by validate_receipt when receipt['estimated_retained_payload_bytes'] < receipt['retained_queued_requests'] * FIXTURE['content_bytes_per_request'], from validate_baseline_receipt or compare.","commonSituations":"An estimator changed to count headers only and not body bytes; content_bytes_per_request in the fixture raised without re-measuring; a stale receipt from an older, smaller fixture.","solutions":["Re-run scripts/measure-persistence-backlog.py so the estimate reflects the current 64 KiB-per-request fixture.","Update the payload estimator to include the full serialized request body, not just metadata.","If retained_queued_requests changed, recompute the payload minimum as retained * 65536 and confirm the receipt meets it."],"exampleFix":"// before\n{\"retained_queued_requests\": 2, \"estimated_retained_payload_bytes\": 65536}  # undercounts\n// after\n{\"retained_queued_requests\": 2, \"estimated_retained_payload_bytes\": 131072}  # 2 * 64 KiB","handlingStrategy":"validation","validationCode":"def payload_covers_content(receipt, bytes_per_request=64 * 1024):\n    return receipt.get(\"estimated_retained_payload_bytes\", 0) >= receipt.get(\"retained_queued_requests\", 0) * bytes_per_request","typeGuard":"def is_non_negative_int(v):\n    return isinstance(v, int) and not isinstance(v, bool) and v >= 0","tryCatchPattern":"try:\n    validate_receipt(receipt)\nexcept PersistenceBacklogError as e:\n    print(f\"payload estimate rejected: {e}\", file=sys.stderr)\n    sys.exit(2)","preventionTips":["Keep the estimator in sync with content_bytes_per_request whenever the fixture changes.","Include full serialized bodies (not just headers) in the payload estimate.","Re-measure after any fixture change instead of reusing old receipts."],"tags":["measurement","validation","payload","python"],"backgroundTag":"value-out-of-range","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}