Hmbown/CodeWhale · error · PersistenceBacklogError

receipt must remain , got

Error message

receipt {field} must remain {expected!r}, got {value!r}

What it means

validate_frozen_field enforces that certain receipt fields are frozen: their value (and exact type) must still equal a pinned expected value. A mismatch raises PersistenceBacklogError with both the expected and actual values, preventing a stale or tampered persistence-backlog receipt from being accepted after the source identity or pinned constants changed.

Solutions

  1. Regenerate the receipt with the current source so the frozen fields match (usually a refresh/regenerate command in the same script)
  2. If the frozen constant legitimately changed, update the pinned expected value alongside the receipt
  3. Discard hand-edits to the receipt and recreate it from the producing pipeline
  4. Commit the refreshed receipt together with the source change that invalidated it

Example fix

# regenerate the receipt so the frozen field matches current source
python scripts/check-persistence-backlog-budget.py --refresh-receipt
python scripts/check-persistence-backlog-budget.py  # now passes
Defensive patterns

Strategy: try-catch

Validate before calling

# compare the receipt's frozen field against the current expected value before checking
expected = current_source_identity()["hash"]
assert receipt["source_hash"] == expected, "receipt is stale; regenerate it"

Try / catch

try:
    validate_receipt(doc)
except PersistenceBacklogError as exc:
    print(f"stale/tampered receipt: {exc}")
    print("regenerate the receipt against current source and commit it")
    sys.exit(1)

Prevention

When it happens

Trigger: Running the budget checker with a receipt generated against different source content than the current tree — e.g. the receipt was committed earlier and since then a pinned field (like a source hash, identity string, or budget constant) changed, or the receipt was hand-edited.

Common situations: Forgetting to regenerate the receipt after modifying tracked source files; rebasing onto commits that changed the frozen constants; CI comparing a receipt from an older run against new code; manual edits to the receipt JSON.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

def load_json(path: Path, label: str) -> dict[str, Any]:
    try:
        value = json.loads(path.read_text(encoding="utf-8"))
    except (OSError, json.JSONDecodeError) as error:
        raise PersistenceBacklogError(f"invalid {label} {path}: {error}") from error
    if not isinstance(value, dict):
        raise PersistenceBacklogError(f"{label} must be a JSON object")
    return value


def non_negative_integer(value: Any, field: str) -> int:
    if isinstance(value, bool) or not isinstance(value, int) or value < 0:
        raise PersistenceBacklogError(f"{field} must be a non-negative integer")
    return value


def validate_frozen_field(field: str, value: Any, expected: Any) -> None:
    if type(value) is not type(expected) or value != expected:
        raise PersistenceBacklogError(
            f"receipt {field} must remain {expected!r}, got {value!r}"
        )


def current_source_identity() -> dict[str, Any]:
    def run(command: list[str]) -> str:
        result = subprocess.run(
            command,
            cwd=ROOT,
            text=True,
            capture_output=True,
            check=False,
        )
        if result.returncode != 0:
            raise PersistenceBacklogError(
                f"source provenance command failed: {' '.join(command)}"
            )
        return result.stdout.strip()

View on GitHub (pinned to 433685b202)