{"record":{"id":"1002e64ad3b1b748","repo":"Hmbown/CodeWhale","slug":"estimated-retained-payload-bytes-is-smaller-than-t","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":"exception","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/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-persistence-backlog-budget.py#L184-L220","documentation":"Raised in validate_receipt (scripts/check-persistence-backlog-budget.py:200-204) when estimated_retained_payload_bytes < retained_queued_requests * 65536 (FIXTURE content_bytes_per_request). Each fixture request carries 64 KiB of content, so the retained payload estimate can never be smaller than retained count times that floor — otherwise the estimator is under-measuring.","triggerScenarios":"The estimator measuring compressed or truncated size instead of serialized JSON bytes; payloads generated smaller than 64 KiB after a fixture change; counting bytes of only the first request; unit confusion (KB vs bytes).","commonSituations":"Session serialization switched to a compact encoding; content generator changed; estimator reading a length field instead of the actual buffer length.","solutions":["Verify the fixture generator still produces exactly 64 KiB of content per request.","Fix the estimator to measure the serialized retained JSON byte length, then regenerate the receipt.","Cross-check estimated_retained_payload_bytes against retained_queued_requests * 65536 in the new receipt."],"exampleFix":"// receipt (before)\n\"retained_queued_requests\": 128, \"estimated_retained_payload_bytes\": 1000\n// receipt (after)\n\"retained_queued_requests\": 128, \"estimated_retained_payload_bytes\": 8388608","handlingStrategy":"validation","validationCode":"min_bytes = receipt[\"retained_queued_requests\"] * 64 * 1024\nif receipt[\"estimated_retained_payload_bytes\"] < min_bytes:\n    sys.exit(\"payload estimator under-measures the 64 KiB-per-request fixture content\")","typeGuard":null,"tryCatchPattern":"try:\n    validate_receipt(receipt)\nexcept PersistenceBacklogError as e:\n    if \"smaller than the frozen retained content\" in str(e):\n        raise RuntimeError(\"estimator returns compressed/truncated size; measure serialized bytes\") from e\n    raise","preventionTips":["Keep the fixture generator at exactly 64 KiB content per request and assert it in tests.","Measure serialized JSON byte length, not compressed size or a stored length field.","Re-verify the estimator whenever the session serialization format changes."],"tags":["measurement","validation","payload"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}