Hmbown/CodeWhale · error · PersistenceBacklogError
{field} must be a non-negative integer
Error message
{field} must be a non-negative integer What it means
non_negative_integer is the checker's field validator for counts in the budget and receipt documents. It rejects a value that is a bool (bools are ints in Python but explicitly disallowed), not an int (floats and strings fail), or negative. The message interpolates the offending field name so you know exactly which key broke the contract.
Source
Thrown at scripts/check-persistence-backlog-budget.py:98
class PersistenceBacklogError(ValueError):
"""A receipt or budget broke the measurement contract."""
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,View on GitHub (pinned to 8880682c63)
Solutions
- Find the named field in the budget/receipt JSON and set it to a whole number >= 0.
- If the value comes from a generator script, coerce with int(round(x)) at write time and assert non-negative before serializing.
- Remove booleans — numeric contract fields take 0/1, not true/false.
- Re-run the checker; field-level errors are reported one at a time, so iterate until the document validates.
Example fix
# before
{"max_files": 5000.0, "max_retries": -1}
# after
{"max_files": 5000, "max_retries": 0} Defensive patterns
Strategy: validation
Validate before calling
def is_non_negative_integer(value: object) -> bool:
return isinstance(value, int) and not isinstance(value, bool) and value >= 0 Type guard
def is_count_field(value: object) -> bool:
# accepts only true ints in [0, 2**63-1]; rejects bools, floats, strings
return (
isinstance(value, int)
and not isinstance(value, bool)
and 0 <= value <= 2**63 - 1
) Prevention
- Write whole numbers without decimal points in budget/receipt JSON (5000, not 5000.0).
- Coerce counts with int() and assert non-negativity in generator scripts before serializing.
- Never use true/false where the contract expects 0/1.
When it happens
Trigger: A budget field like "max_files": -1 or 5000.0; a receipt count serialized as a string ("3") by another language's JSON writer; a boolean true/false left in place of a numeric flag. All raise before any comparison against the baseline runs.
Common situations: Hand-editing the budget and using a float or negative sentinel; receipts generated by measurement tooling in JS/Go that emits strings or floats for counts; JSON serializers that write 0.0 or 1e3; someone using true as shorthand for 1.
Related errors
- invalid {label} {path}: {error}
- {label} must be a JSON object
- baseline provenance build profile/sample count changed
- {kind} field `{dotted_names}` must be sorted unique non-empt
- ${label} does not match the authoritative inventory; missing
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/1d89c4e36083a136.
Report an issue: GitHub.