{"record":{"id":"4f6d251104112914","repo":"Hmbown/CodeWhale","slug":"source-document-kind-must-be-expected-kind-got-actual-kind-r","errorCode":null,"errorMessage":"{source} document_kind must be `{expected_kind}`, got {actual_kind!r}","messagePattern":"(.+?) document_kind must be `(.+?)`, got (.+?)","errorType":"console","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":177,"sourceCode":"\ndef load_json(path: Path, kind: str) -> dict[str, Any]:\n    try:\n        document = json.loads(path.read_text(encoding=\"utf-8\"))\n    except FileNotFoundError as error:\n        raise RuntimeContractError(f\"missing {kind}: {path}\") from error\n    except (OSError, json.JSONDecodeError) as error:\n        raise RuntimeContractError(f\"invalid {kind} {path}: {error}\") from error\n    if not isinstance(document, dict):\n        raise RuntimeContractError(f\"invalid {kind} {path}: top level must be an object\")\n    return document\n\n\ndef validate_document(\n    document: dict[str, Any], expected_kind: str, source: str\n) -> None:\n    actual_kind = document.get(\"document_kind\")\n    if actual_kind != expected_kind:\n        raise RuntimeContractError(\n            f\"{source} document_kind must be `{expected_kind}`, got {actual_kind!r}\"\n        )\n    version = document.get(\"schema_version\")\n    if (\n        isinstance(version, bool)\n        or not isinstance(version, int)\n        or version != SCHEMA_VERSION\n    ):\n        raise RuntimeContractError(\n            f\"{source} schema_version must be {SCHEMA_VERSION}, got {version!r}\"\n        )\n\n\ndef required_value(document: dict[str, Any], path: MetricPath, kind: str) -> Any:\n    value: Any = document\n    dotted = \".\".join(path)\n    for part in path:\n        if not isinstance(value, dict) or part not in value:","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-runtime-contract-budget.py#L159-L195","documentation":"validate_document checks that a parsed receipt/budget JSON has the required `document_kind` discriminator equal to the expected kind (codewhale.runtime_contract_receipt or codewhale.runtime_contract_budget). A mismatch or missing key raises this RuntimeContractError, preventing a receipt from being validated as a budget or vice versa.","triggerScenarios":"Passing a budget JSON via --receipt (or the receipt path to the budget loader); a document missing document_kind entirely; an old or differently-named discriminator field.","commonSituations":"Swapping the two file arguments; pointing the checker at an unrelated JSON config; a schema rename between tool versions left an old file with a stale document_kind.","solutions":["Check the `got` value in the message: pass the receipt file to --receipt and keep scripts/runtime-contract-budget.json as the budget input.","Set document_kind to the expected string (\"codewhale.runtime_contract_receipt\" or \"codewhale.runtime_contract_budget\") if the file's kind was renamed.","Regenerate the document with the current tool version if it predates the schema rename."],"exampleFix":"// before (receipt.json)\n{\"document_kind\": \"codewhale.runtime_contract_budget\", ...}\n// after\n{\"document_kind\": \"codewhale.runtime_contract_receipt\", ...}","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\ndoc = json.loads(Path(path).read_text(encoding=\"utf-8\"))\nexpected = \"codewhale.runtime_contract_receipt\"\nif doc.get(\"document_kind\") != expected:\n    raise SystemExit(f\"{path}: document_kind must be {expected!r}\")","typeGuard":"def has_document_kind(doc, kind: str) -> bool:\n    return isinstance(doc, dict) and doc.get(\"document_kind\") == kind","tryCatchPattern":"try:\n    validate_document(doc, RECEIPT_KIND, \"receipt\")\nexcept RuntimeContractError as e:\n    print(e); sys.exit(1)  # message shows expected vs actual kind","preventionTips":["Never swap the receipt and budget files; keep their names distinct (receipt.json vs runtime-contract-budget.json).","Include document_kind in every generated contract document and assert it at write time.","If renaming the discriminator, bump schema_version and migrate old files."],"tags":["python","json","schema","validation"],"backgroundTag":"schema-validation-failed","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"}