Hmbown/CodeWhale · error · PersistenceBacklogError

receipt missing required field(s): " + ", ".join(missing)

Error message

receipt missing required field(s): " + ", ".join(missing)

What it means

Raised in validate_receipt (scripts/check-persistence-backlog-budget.py:142-146) when any of the 29 REQUIRED_RECEIPT_FIELDS (document_kind through limitations) is absent from the receipt JSON. The checker demands a complete, closed schema so partial receipts cannot silently pass the budget gate.

Source

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

        "source_dirty": bool(
            run(["git", "status", "--porcelain", "--untracked-files=normal"])
        ),
        "rustc_version": run(["rustc", "--version"]),
        "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")

View on GitHub (pinned to 8880682c63)

Solutions

  1. Regenerate the receipt via scripts/measure-persistence-backlog.py so all current fields are emitted.
  2. If you added a receipt field, also add it to the Rust test's receipt writer and to REQUIRED_RECEIPT_FIELDS in the same commit.
  3. Delete stale receipt artifacts from CI caches so the fresh emitter output is always used.

Example fix

// receipt (before, older schema)
{ "document_kind": "...", "schema_version": 2 }
// receipt (after, complete)
{ "document_kind": "...", "schema_version": 2, /* ...all 29 required keys... */ "limitations": ["..."] }
Defensive patterns

Strategy: type-guard

Validate before calling

missing = [f for f in REQUIRED_RECEIPT_FIELDS if f not in receipt]
if missing:
    raise SystemExit(f"incomplete receipt, regenerate: missing {', '.join(missing)}")

Type guard

def has_all_required_fields(receipt: dict) -> bool:
    return all(field in receipt for field in REQUIRED_RECEIPT_FIELDS)

Try / catch

try:
    validate_receipt(receipt)
except PersistenceBacklogError as e:
    if str(e).startswith("receipt missing required field"):
        # schema drift: regenerate instead of patching fields in
        subprocess.run([sys.executable, "scripts/measure-persistence-backlog.py"], check=True)
    raise

Prevention

When it happens

Trigger: Checking a receipt written by an older schema (missing newer fields like rss_*); a truncated or hand-built JSON; the Rust test failing to populate a field; a typo'd key in the emitter (e.g. "final_version_applied" vs "finalVersionApplied").

Common situations: Schema evolution where a field was added to REQUIRED_RECEIPT_FIELDS but old receipts linger; reusing a CI-cached receipt artifact; manual receipt construction for testing.

Related errors


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