{"record":{"id":"8ac95eb70e134b6e","repo":"Hmbown/CodeWhale","slug":"kind-metric-dotted-must-be-a-non-negative-integer","errorCode":null,"errorMessage":"{kind} metric `{dotted}` must be a non-negative integer","messagePattern":"(.+?) metric `(.+?)` must be a non-negative integer","errorType":"exception","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":306,"sourceCode":"    representative = budget.get(\"representative_context\")\n    fixture_id = (\n        representative.get(\"fixture_id\")\n        if isinstance(representative, dict)\n        else None\n    )\n    if fixture_id != REPRESENTATIVE_FIXTURE_ID:\n        raise RuntimeContractError(\n            \"budget metric `representative_context.fixture_id` must be \"\n            f\"`{REPRESENTATIVE_FIXTURE_ID}`, got {fixture_id!r}\"\n        )\n    validate_identity_structure(budget, \"budget\")\n\n\ndef metric_value(document: dict[str, Any], path: MetricPath, kind: str) -> int:\n    value = required_value(document, path, kind)\n    dotted = \".\".join(path)\n    if isinstance(value, bool) or not isinstance(value, int) or value < 0:\n        raise RuntimeContractError(\n            f\"{kind} metric `{dotted}` must be a non-negative integer\"\n        )\n    return value\n\n\ndef compare(\n    receipt: dict[str, Any], budget: dict[str, Any]\n) -> tuple[list[MetricResult], list[MetricResult]]:\n    \"\"\"Return (increases, decreases) as path/label/current/ceiling tuples.\"\"\"\n    validate_receipt(receipt)\n    validate_budget(budget)\n    for path, label in IDENTITIES:\n        receipt_value = required_value(receipt, path, \"receipt\")\n        budget_value = required_value(budget, path, \"budget\")\n        if receipt_value != budget_value:\n            detail = \"\"\n            if isinstance(receipt_value, list) and isinstance(budget_value, list):\n                added = [str(item) for item in receipt_value if item not in budget_value]","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/check-runtime-contract-budget.py#L288-L324","documentation":"metric_value reads a dotted metric path (e.g. `system_prompt.modes.plan.system_prompt_bytes`) from a receipt or budget document and enforces that every tracked metric is a non-negative integer. It rejects missing values (via required_value), booleans (a bool is an int in Python but not a valid metric), non-int types, and negative numbers. This guards the budget comparison math from floats, strings, and signed garbage.","triggerScenarios":"Calling metric_value via validate_identity_structure, compare, or budget_from_receipt on a document where a metric at a METRICS path is a bool, float, string, negative int, or missing; e.g. a receipt produced by a broken or hand-edited measurement.","commonSituations":"A measurement script emitted a float (e.g. 1234.0) or null for a metric; someone hand-edited the budget JSON with a string value; a schema change renamed a key so required_value surfaces through the same check; JSON produced by a non-Python tool used `true` for a counter.","solutions":["Locate the offending dotted path printed in the message and set it to a non-negative integer in the receipt/budget JSON.","Re-run `python3 scripts/measure-runtime-contract.py` to regenerate the receipt instead of hand-editing values.","Check that the value is not a float/string in the emitting tool (e.g. cast int(...) in the measurement script).","If the metric schema changed, update METRICS in the checker and regenerate both receipt and budget together."],"exampleFix":"// before (receipt JSON)\n\"system_prompt_bytes\": 12804.0\n// after\n\"system_prompt_bytes\": 12804","handlingStrategy":"validation","validationCode":"def check_metrics(doc: dict, paths) -> None:\n    for path in paths:\n        node = doc\n        for key in path:\n            node = node[key]\n        if isinstance(node, bool) or not isinstance(node, int) or node < 0:\n            raise ValueError(f\"{'.'.join(path)} must be a non-negative int, got {node!r}\")","typeGuard":"def is_metric(value: object) -> bool:\n    return isinstance(value, int) and not isinstance(value, bool) and value >= 0","tryCatchPattern":"try:\n    receipt = json.loads(proc.stdout)\n    check_metrics(receipt, metric_paths)\nexcept (json.JSONDecodeError, KeyError, ValueError) as e:\n    print(f\"invalid receipt: {e}\", file=sys.stderr)","preventionTips":["Emit metrics with int() casts in the measurement script.","Never hand-edit receipts; always generate them from the measurement.","Validate receipt shape with jsonschema before handing it to the checker."],"tags":["validation","schema","metrics","contract-check"],"backgroundTag":"schema-validation-failed","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}