{"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":"validation","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/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-persistence-backlog-budget.py#L130-L166","documentation":"`validate_receipt` requires that `document_kind` equal the exact string `codewhale.persistence_backlog_receipt`. This discriminator marks the JSON document as a persistence backlog measurement receipt and prevents a budget file or other document from being validated as a receipt. A wrong kind means the file is not the artifact this validator accepts.","triggerScenarios":"Pointing `--receipt` at the budget JSON (`codewhale.persistence_backlog_budget`) or at the baseline receipt reference with an edited document_kind; a typo or rename of document_kind in a hand-written receipt.","commonSituations":"Swapping the --receipt and --budget argument values by mistake; renaming document_kind to a project-local value; generating a receipt with an out-of-tree tool that uses a different kind string.","solutions":["Set `document_kind` to exactly `\"codewhale.persistence_backlog_receipt\"` in the receipt JSON","Verify you did not pass the budget file via `--receipt` (the budget uses kind `codewhale.persistence_backlog_budget`)","Regenerate the receipt with the measurement script so the kind is set correctly"],"exampleFix":"// before\n{\"document_kind\": \"codewhale.persistence_backlog_budget\", ...}\n// after\n{\"document_kind\": \"codewhale.persistence_backlog_receipt\", ...}","handlingStrategy":"validation","validationCode":"assert receipt.get(\"document_kind\") == \"codewhale.persistence_backlog_receipt\", receipt.get(\"document_kind\")","typeGuard":"def is_receipt(doc):\n    return isinstance(doc, dict) and doc.get(\"document_kind\") == \"codewhale.persistence_backlog_receipt\"","tryCatchPattern":"try:\n    validate_receipt(receipt)\nexcept PersistenceBacklogError as e:\n    if \"document_kind\" in str(e):\n        check_arguments_for_swapped_receipt_and_budget()","preventionTips":["Double-check you pass the receipt file to --receipt and the budget to --budget","Copy document_kind verbatim from the baseline receipt","Never rename document_kind in receipts"],"tags":["validation","json","schema","receipt"],"backgroundTag":"invalid-enum-value","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"}