Hmbown/CodeWhale · error · PersistenceBacklogError
limitations must be a non-empty string array
Error message
limitations must be a non-empty string array
What it means
Raised in validate_receipt (scripts/check-persistence-backlog-budget.py:213-217) when limitations is not a list, is empty, or contains a non-string or empty string. Every measurement receipt must carry at least one honest caveat about the measurement, so unqualified numbers cannot be presented as absolute.
Source
Thrown at scripts/check-persistence-backlog-budget.py:217
)
minimum_payload_bytes = retained * FIXTURE["content_bytes_per_request"]
if receipt["estimated_retained_payload_bytes"] < minimum_payload_bytes:
raise PersistenceBacklogError(
"estimated_retained_payload_bytes is smaller than the frozen retained content"
)
applied = non_negative_integer(
receipt["applied_version"], "applied_version"
)
if applied != FIXTURE["expected_applied_version"]:
raise PersistenceBacklogError("applied_version is not the final sent version")
if receipt["final_version_applied"] is not True:
raise PersistenceBacklogError("final_version_applied must be true")
limitations = receipt["limitations"]
if not isinstance(limitations, list) or not limitations or not all(
isinstance(item, str) and item for item in limitations
):
raise PersistenceBacklogError("limitations must be a non-empty string array")
if not isinstance(receipt["rss_supported"], bool):
raise PersistenceBacklogError("rss_supported must be boolean")
if receipt["rss_supported"] != (platform == "macos"):
raise PersistenceBacklogError(
"rss_supported must be true exactly on the macOS measurement lane"
)
rss_fields = RSS_SAMPLE_FIELDS + RSS_DELTA_FIELDS
if receipt["rss_supported"]:
for field in rss_fields:
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"] - beforeView on GitHub (pinned to 8880682c63)
Solutions
- Restore the limitations list in the Rust measurement test with at least one meaningful string (e.g. single-sample variance, platform specificity).
- Regenerate the receipt.
- Keep the field non-optional in any schema refactor — the checker enforces non-emptiness.
Example fix
// receipt (before) "limitations": [] // receipt (after) "limitations": ["single-sample measurement; variance not captured"]
Defensive patterns
Strategy: type-guard
Validate before calling
lim = receipt.get("limitations")
if not isinstance(lim, list) or not lim or not all(isinstance(s, str) and s for s in lim):
sys.exit("limitations must be a non-empty array of non-empty strings") Type guard
def is_valid_limitations(value) -> bool:
return isinstance(value, list) and len(value) > 0 and all(isinstance(s, str) and s for s in value) Try / catch
try:
validate_receipt(receipt)
except PersistenceBacklogError as e:
if "limitations" in str(e):
raise RuntimeError("receipt lacks measurement caveats; restore the emitter's limitations block") from e
raise Prevention
- Always emit at least one caveat (e.g. single-sample variance) in the Rust writer.
- Keep limitations mandatory in schema refactors.
- Never trim limitations when hand-reviewing receipt JSON.
When it happens
Trigger: The Rust emitter writing [] or omitting caveats; null entries; whitespace-only strings; a schema change that moved limitations elsewhere without updating the emitter.
Common situations: Emitter simplification that dropped the caveats block; receipts from an older schema where limitations was optional; hand-trimmed JSON.
Related errors
- Codewhale terminal receipt exceeded its total bound
- Codewhale stream-json line {line_number} was not an object
- invalid {label} {path}: {error}
- {label} must be a JSON object
- {field} must be a non-negative integer
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/50ce881425833fdf.
Report an issue: GitHub.