Hmbown/CodeWhale · error · PersistenceBacklogError
budget fixture. must remain
Error message
budget fixture.{field} must remain {expected!r} What it means
After the key-set check, validate_budget compares each fixture field's type and value against the script's frozen FIXTURE constants. If any fixture field was changed (e.g. requests_attempted bumped from 128 to 256), the budget describes a different workload than the one the ceilings were calibrated for, so the check fails with this field-specific message naming the expected value.
Solutions
- Revert the edited fixture field to the exact frozen value reported in the error message
- Regenerate the budget from the current measurement pipeline
- If the workload must change, update FIXTURE in the script first and recalibrate ceilings and baseline_observation in the same commit
Example fix
// before "requests_attempted": 256 // after "requests_attempted": 128
Defensive patterns
Strategy: validation
Validate before calling
from check_persistence_backlog_budget import FIXTURE
fixture = budget.get("fixture", {})
for field, expected in FIXTURE.items():
assert type(fixture.get(field)) is type(expected) and fixture.get(field) == expected, f"fixture.{field} must remain {expected!r}" Type guard
def fixture_matches(doc):
f = doc.get("fixture") if isinstance(doc, dict) else None
return isinstance(f, dict) and all(type(f.get(k)) is type(v) and f.get(k) == v for k, v in FIXTURE.items()) Try / catch
try:
validate_budget(budget)
except PersistenceBacklogError as e:
if ".must remain" in str(e) and "fixture" in str(e):
print("restore the frozen fixture value named in the message")
raise Prevention
- Treat FIXTURE values as immutable constants; change workload size only via a script + budget regeneration commit
- Beware JSON round-trips that turn ints into floats — the check is strict on type()
- Never hand-edit fixture numbers to make a ceiling check pass
When it happens
Trigger: compare calls validate_budget and any fixture field differs in type (strict type() check, so true vs 1 fails) or value from FIXTURE, e.g. content_bytes_per_request changed or expected_applied_version edited.
Common situations: Tuning the workload numbers by hand in the budget JSON to make a failing ceiling pass; editing fixture values with a different numeric type (float 128.0 instead of int 128); stale budget from a pre-existing fixture revision.
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
- baseline_observation.accepted_requests must equal…
- budget fixture no longer matches the frozen workload
- applied_version is not the final sent version
- baseline_observation.
- budget baseline_receipt path changed
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/11edfe07c17b67e4.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/check-persistence-backlog-budget.py:252
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}"
)
if observed > ceiling:
raise PersistenceBacklogError(
f"baseline_observation.{field} exceeds its ceiling"
)
baseline_accepted = non_negative_integer(View on GitHub (pinned to 433685b202)