Hmbown/CodeWhale · error · PersistenceBacklogError

receipt document_kind must be {RECEIPT_KIND}

Error message

receipt document_kind must be {RECEIPT_KIND}

What it means

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.

Source

Thrown at scripts/check-persistence-backlog-budget.py:148

        "cargo_version": run(["cargo", "--version"]),
        "build_profile": "test",
        "sample_count": 1,
    }


def validate_receipt(
    receipt: dict[str, Any],
    *,
    expected_source: dict[str, Any] | None = None,
    require_clean_source: bool = False,
) -> None:
    missing = [field for field in REQUIRED_RECEIPT_FIELDS if field not in receipt]
    if missing:
        raise PersistenceBacklogError(
            "receipt missing required field(s): " + ", ".join(missing)
        )
    if receipt["document_kind"] != RECEIPT_KIND:
        raise PersistenceBacklogError(f"receipt document_kind must be {RECEIPT_KIND}")
    if receipt["schema_version"] != SCHEMA_VERSION:
        raise PersistenceBacklogError("receipt schema_version changed")
    for field, expected in FIXTURE.items():
        validate_frozen_field(field, receipt[field], expected)
    if not isinstance(receipt["source_sha"], str) or not SOURCE_SHA_PATTERN.fullmatch(
        receipt["source_sha"]
    ):
        raise PersistenceBacklogError("receipt source_sha must be an exact lowercase Git SHA")
    if type(receipt["source_dirty"]) is not bool:
        raise PersistenceBacklogError("receipt source_dirty must be boolean")
    for field, prefix in (("rustc_version", "rustc "), ("cargo_version", "cargo ")):
        if not isinstance(receipt[field], str) or not receipt[field].startswith(prefix):
            raise PersistenceBacklogError(f"receipt {field} must be a version string")
    validate_frozen_field("build_profile", receipt["build_profile"], "test")
    validate_frozen_field("sample_count", receipt["sample_count"], 1)
    if expected_source is not None:
        for field in (
            "source_sha",

View on GitHub (pinned to 8880682c63)

Solutions

  1. Point --receipt at the JSON emitted by scripts/measure-persistence-backlog.py, not at the budget or baseline files.
  2. Omit --receipt entirely to have the checker measure fresh.
  3. If you renamed the kind, update RECEIPT_KIND and regenerate every receipt artifact together.

Example fix

# before
python scripts/check-persistence-backlog-budget.py --receipt scripts/persistence-backlog-budget.json
# after
python scripts/check-persistence-backlog-budget.py --receipt /tmp/receipt-from-measure.json
Defensive patterns

Strategy: type-guard

Validate before calling

if receipt.get("document_kind") != "codewhale.persistence_backlog_receipt":
    sys.exit("wrong document: pass the measurement receipt, not the budget/baseline JSON")

Type guard

def is_backlog_receipt(doc: dict) -> bool:
    return doc.get("document_kind") == "codewhale.persistence_backlog_receipt"

Try / catch

try:
    validate_receipt(doc)
except PersistenceBacklogError as e:
    if "document_kind" in str(e):
        raise ValueError("passed a budget or unrelated JSON as --receipt") from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: Mixing up the two JSON files in scripts/ when invoking the checker manually; copy-pasting a --receipt path from older docs.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/3e96bf6d834e0498. Report an issue: GitHub.