{"record":{"id":"3e96bf6d834e0498","repo":"Hmbown/CodeWhale","slug":"receipt-document-kind-must-be-receipt-kind","errorCode":null,"errorMessage":"receipt document_kind must be {RECEIPT_KIND}","messagePattern":"receipt document_kind must be (.+?)","errorType":"exception","errorClass":"PersistenceBacklogError","httpStatus":null,"severity":"error","filePath":"scripts/check-persistence-backlog-budget.py","lineNumber":148,"sourceCode":"        \"cargo_version\": run([\"cargo\", \"--version\"]),\n        \"build_profile\": \"test\",\n        \"sample_count\": 1,\n    }\n\n\ndef validate_receipt(\n    receipt: dict[str, Any],\n    *,\n    expected_source: dict[str, Any] | None = None,\n    require_clean_source: bool = False,\n) -> None:\n    missing = [field for field in REQUIRED_RECEIPT_FIELDS if field not in receipt]\n    if missing:\n        raise PersistenceBacklogError(\n            \"receipt missing required field(s): \" + \", \".join(missing)\n        )\n    if receipt[\"document_kind\"] != RECEIPT_KIND:\n        raise PersistenceBacklogError(f\"receipt document_kind must be {RECEIPT_KIND}\")\n    if receipt[\"schema_version\"] != SCHEMA_VERSION:\n        raise PersistenceBacklogError(\"receipt schema_version changed\")\n    for field, expected in FIXTURE.items():\n        validate_frozen_field(field, receipt[field], expected)\n    if not isinstance(receipt[\"source_sha\"], str) or not SOURCE_SHA_PATTERN.fullmatch(\n        receipt[\"source_sha\"]\n    ):\n        raise PersistenceBacklogError(\"receipt source_sha must be an exact lowercase Git SHA\")\n    if type(receipt[\"source_dirty\"]) is not bool:\n        raise PersistenceBacklogError(\"receipt source_dirty must be boolean\")\n    for field, prefix in ((\"rustc_version\", \"rustc \"), (\"cargo_version\", \"cargo \")):\n        if not isinstance(receipt[field], str) or not receipt[field].startswith(prefix):\n            raise PersistenceBacklogError(f\"receipt {field} must be a version string\")\n    validate_frozen_field(\"build_profile\", receipt[\"build_profile\"], \"test\")\n    validate_frozen_field(\"sample_count\", receipt[\"sample_count\"], 1)\n    if expected_source is not None:\n        for field in (\n            \"source_sha\",","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-persistence-backlog-budget.py#L130-L166","documentation":"Raised in validate_receipt (scripts/check-persistence-backlog-budget.py:147-148) when receipt[\"document_kind\"] != \"codewhale.persistence_backlog_receipt\". The kind tag discriminates document types so the checker never mistakes a budget or unrelated JSON for a measurement receipt.","triggerScenarios":"Passing --receipt scripts/persistence-backlog-budget.json (whose document_kind is codewhale.persistence_backlog_budget); passing an arbitrary JSON file; a receipt from a pre-kind era or with the tag renamed.","commonSituations":"Mixing up the two JSON files in scripts/ when invoking the checker manually; copy-pasting a --receipt path from older docs.","solutions":["Point --receipt at the JSON emitted by scripts/measure-persistence-backlog.py, not at the budget or baseline files.","Omit --receipt entirely to have the checker measure fresh.","If you renamed the kind, update RECEIPT_KIND and regenerate every receipt artifact together."],"exampleFix":"# before\npython scripts/check-persistence-backlog-budget.py --receipt scripts/persistence-backlog-budget.json\n# after\npython scripts/check-persistence-backlog-budget.py --receipt /tmp/receipt-from-measure.json","handlingStrategy":"type-guard","validationCode":"if receipt.get(\"document_kind\") != \"codewhale.persistence_backlog_receipt\":\n    sys.exit(\"wrong document: pass the measurement receipt, not the budget/baseline JSON\")","typeGuard":"def is_backlog_receipt(doc: dict) -> bool:\n    return doc.get(\"document_kind\") == \"codewhale.persistence_backlog_receipt\"","tryCatchPattern":"try:\n    validate_receipt(doc)\nexcept PersistenceBacklogError as e:\n    if \"document_kind\" in str(e):\n        raise ValueError(\"passed a budget or unrelated JSON as --receipt\") from e\n    raise","preventionTips":["Name generated receipts distinctly from scripts/persistence-backlog-budget.json.","Check document_kind before handing any JSON to the checker.","Let the checker measure fresh (omit --receipt) when in doubt."],"tags":["validation","json","document-kind"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}