Hmbown/CodeWhale · error · PersistenceBacklogError

receipt schema_version changed

Error message

receipt schema_version changed

What it means

The receipt's `schema_version` must equal the constant `SCHEMA_VERSION = 2` defined in scripts/check-persistence-backlog-budget.py:23. If a receipt was produced by an older (version 1) or newer producer whose schema layout no longer matches what this validator expects, the check refuses to interpret the fields. This guards against silently validating a document whose semantics changed between releases.

Solutions

  1. Regenerate the receipt with the current scripts/measure-persistence-backlog.py so schema_version is 2
  2. Set `schema_version` to the integer 2 in the receipt (note: it must be the number 2, not the string "2")
  3. Update the checker and measurement scripts together from the same commit so their schema versions match

Example fix

// before
{"schema_version": "2", ...}
// after
{"schema_version": 2, ...}
Defensive patterns

Strategy: validation

Validate before calling

assert receipt.get("schema_version") == 2, receipt.get("schema_version")

Type guard

def is_current_schema(doc):
    return isinstance(doc, dict) and doc.get("schema_version") is 2 if isinstance(doc, dict) and type(doc.get("schema_version")) is int else False

Try / catch

try:
    validate_receipt(receipt)
except PersistenceBacklogError as e:
    if "schema_version changed" in str(e):
        receipt = regenerate_receipt()  # re-measure with current scripts

Prevention

When it happens

Trigger: Validating a receipt JSON with `schema_version` of 1, 3, or a string like "2"; the measurement script and the checking script were updated out of sync in different branches.

Common situations: Reusing a committed receipt from before a schema bump; merging an old branch's receipt with the new checker; hand-written receipts copied from old documentation.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/71f2cbcf96580d7b. Report an issue: GitHub.

Appendix: source

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

        "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",
            "source_dirty",
            "rustc_version",

View on GitHub (pinned to 433685b202)