Hmbown/CodeWhale · error · PersistenceBacklogError

budget schema_version changed

Error message

budget schema_version changed

What it means

Raised by validate_budget() when budget['schema_version'] != 2 (SCHEMA_VERSION frozen in the checker). Budget and receipt schemas are version-frozen together, so a mismatch means the document was written for a different generation of the contract and every later field check would be unreliable. The same constant gates receipts (validate_receipt raises the parallel 'receipt schema_version changed'), so a schema bump invalidates both documents at once.

Source

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

            non_negative_integer(receipt[field], field)
        before = receipt["rss_before_bytes"]
        if receipt["rss_during_delta_bytes"] != max(
            0, receipt["rss_during_bytes"] - before
        ):
            raise PersistenceBacklogError("rss_during_delta_bytes is inconsistent")
        if receipt["rss_after_delta_bytes"] != max(
            0, receipt["rss_after_bytes"] - before
        ):
            raise PersistenceBacklogError("rss_after_delta_bytes is inconsistent")
    elif any(receipt[field] is not None for field in rss_fields):
        raise PersistenceBacklogError("unsupported RSS fields must be null")


def validate_budget(budget: dict[str, Any]) -> None:
    if budget.get("document_kind") != BUDGET_KIND:
        raise PersistenceBacklogError(f"budget document_kind must be {BUDGET_KIND}")
    if budget.get("schema_version") != SCHEMA_VERSION:
        raise PersistenceBacklogError("budget schema_version changed")
    fixture = budget.get("fixture")
    if not isinstance(fixture, dict) or set(fixture) != set(FIXTURE):
        raise PersistenceBacklogError("budget fixture no longer matches the frozen workload")
    for field, expected in FIXTURE.items():
        if type(fixture[field]) is not type(expected) or fixture[field] != expected:
            raise PersistenceBacklogError(
                f"budget fixture.{field} must remain {expected!r}"
            )
    if budget.get("baseline_receipt") != BASELINE_RECEIPT_REFERENCE:
        raise PersistenceBacklogError("budget baseline_receipt path changed")
    ceilings = budget.get("ceilings")
    baseline = budget.get("baseline_observation")
    if not isinstance(ceilings, dict) or not isinstance(baseline, dict):
        raise PersistenceBacklogError("budget needs ceilings and baseline_observation objects")
    for field in CEILING_FIELDS:
        ceiling = non_negative_integer(ceilings.get(field), f"ceilings.{field}")
        observed = non_negative_integer(
            baseline.get(field), f"baseline_observation.{field}"

View on GitHub (pinned to 8880682c63)

Solutions

  1. Use the budget and checker from the same checkout: scripts/persistence-backlog-budget.json with schema_version 2
  2. If the schema genuinely changed upstream, regenerate both the budget and the baseline receipt with the new tooling instead of hand-bumping the field
  3. Run git status/log on scripts/*.json to detect a stale or mixed-version file

Example fix

// before (budget.json)
"document_kind": "codewhale.persistence_backlog_budget",
"schema_version": 1

// after: regenerate the document with the current tooling
"document_kind": "codewhale.persistence_backlog_budget",
"schema_version": 2
Defensive patterns

Strategy: validation

Validate before calling

def schema_version_ok(doc: dict, expected: int = 2) -> bool:
    v = doc.get("schema_version")
    return isinstance(v, int) and not isinstance(v, bool) and v == expected

Prevention

When it happens

Trigger: Loading a budget whose schema_version is missing, 1, 3, or the string '2' - typically an old budget file checked out against a newer checker, or a budget produced by tooling from a different schema generation.

Common situations: Checking out an old scripts/persistence-backlog-budget.json against a new checker (or vice versa); a schema migration that bumped one document but not the other; hand-editing schema_version hoping to skip re-validation.

Related errors


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