Hmbown/CodeWhale · error · PersistenceBacklogError
budget needs ceilings and baseline_observation objects
Error message
budget needs ceilings and baseline_observation objects
What it means
Raised by validate_budget() when budget['ceilings'] or budget['baseline_observation'] is missing or not a JSON object. Both blocks are required: ceilings holds the one-way upper bounds for the five CEILING_FIELDS and baseline_observation holds the frozen macOS baseline those ceilings were derived from.
Source
Thrown at scripts/check-persistence-backlog-budget.py:260
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(
baseline.get("accepted_requests"), "baseline_observation.accepted_requests"
)
if baseline_accepted != FIXTURE["requests_attempted"]:
raise PersistenceBacklogError(
"baseline_observation.accepted_requests must equal requests_attempted"
)
baseline_applied = non_negative_integer(
baseline.get("applied_version"), "baseline_observation.applied_version"View on GitHub (pinned to 8880682c63)
Solutions
- Restore both objects: ceilings with the five ceiling fields, baseline_observation with its observation fields plus provenance
- Validate the file with python -m json.tool scripts/persistence-backlog-budget.json before running the checker
- Copy the block structure from scripts/persistence-backlog-budget.json at git HEAD
Example fix
// before (budget.json)
{ "document_kind": "...", "schema_version": 2, "fixture": { ... },
"ceilings": { ... } }
// after: both objects present
{ "document_kind": "...", "schema_version": 2, "fixture": { ... },
"ceilings": { ... },
"baseline_observation": { ..., "provenance": { ... } } } Defensive patterns
Strategy: validation
Validate before calling
def budget_blocks_ok(budget: dict) -> bool:
return (isinstance(budget.get("ceilings"), dict)
and isinstance(budget.get("baseline_observation"), dict)) Prevention
- Load budgets from the repo checkout (scripts/persistence-backlog-budget.json) instead of hand-maintained copies
- Validate budget JSON with python -m json.tool and a key-set check before running the checker
- Change FIXTURE/SCHEMA_VERSION in the checker only together with regenerating budget and baseline receipt in one commit
When it happens
Trigger: Either key absent, set to null, an array, a scalar, or a typo such as 'ceiling' or 'baseline_observations'.
Common situations: Truncating the budget during hand-edits; a merge that dropped one block; generating a budget from a template that omitted baseline_observation.
Related errors
- budget document_kind must be {BUDGET_KIND}
- budget fixture no longer matches the frozen workload
- budget baseline_receipt path changed
- rss_during_delta_bytes is inconsistent
- rss_after_delta_bytes is inconsistent
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/c8de3e97ab7b440b.
Report an issue: GitHub.