{"record":{"id":"d5811f5eafd4ea60","repo":"Hmbown/CodeWhale","slug":"measurement-emitted-invalid-json-error-d5811f","errorCode":null,"errorMessage":"measurement emitted invalid JSON: {error}","messagePattern":"measurement emitted invalid JSON: (.+?)","errorType":"exception","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":411,"sourceCode":"    env[\"CARGO_NET_OFFLINE\"] = \"true\"\n    proc = subprocess.run(\n        [sys.executable, str(MEASURE_SCRIPT)],\n        cwd=REPO_ROOT,\n        env=env,\n        capture_output=True,\n        text=True,\n        check=False,\n    )\n    sys.stderr.write(proc.stderr)\n    if proc.returncode != 0:\n        sys.stdout.write(proc.stdout)\n        raise RuntimeContractError(\n            f\"runtime-contract measurement failed with exit code {proc.returncode}\"\n        )\n    try:\n        receipt = json.loads(proc.stdout)\n    except json.JSONDecodeError as error:\n        raise RuntimeContractError(f\"measurement emitted invalid JSON: {error}\") from error\n    if not isinstance(receipt, dict):\n        raise RuntimeContractError(\"measurement top level must be an object\")\n    validate_receipt(receipt)\n    return receipt\n\n\ndef update_command(receipt_path: Path | None, budget_path: Path) -> str:\n    parts = [\"python3\", \"scripts/check-runtime-contract-budget.py\"]\n    if receipt_path is not None:\n        parts.extend([\"--receipt\", str(receipt_path)])\n    if budget_path != BUDGET_PATH:\n        parts.extend([\"--budget\", str(budget_path)])\n    parts.append(\"--update\")\n    return shlex.join(parts)\n\n\nFRAGMENT_MODULE = REPO_ROOT / \"crates\" / \"core\" / \"src\" / \"fragments.rs\"\nFRAGMENT_MAX_TOKENS_CEILING = 10_000","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-runtime-contract-budget.py#L393-L429","documentation":"After a successful measurement, run_measurement() parses the child's entire stdout as JSON to obtain the receipt. If json.loads raises, the raw stdout contained something non-JSON - the receipt printer's output was polluted or truncated. The JSONDecodeError detail (line/column) is embedded in the message to point at the offending byte.","triggerScenarios":"The --nocapture test or the measure script printing diagnostics to stdout (println!/print) instead of stderr; a panic message interleaved into stdout; partial output when the child dies mid-write while still exiting 0; progress bars or cargo notes leaking into the captured pipe.","commonSituations":"A developer adds a debug println! in the metric test and the gate suddenly fails locally; a dependency upgrades and starts writing to stdout; running with a wrapper (rustfilt, backtrace pretty-printers) that injects text.","solutions":["Reproduce and capture: python3 scripts/measure-runtime-contract.py > out.json and inspect around the reported line/column","Route every diagnostic in the measure path to stderr: print(..., file=sys.stderr) in Python, eprintln! in Rust","Pipe the stdout through python3 -m json.tool as a quick validity check before wiring changes back into the gate"],"exampleFix":"# before (measure path)\nprint(f\"measuring {name}\")  # pollutes stdout, breaks json.loads\n\n# after\nimport sys\nprint(f\"measuring {name}\", file=sys.stderr)","handlingStrategy":"try-catch","validationCode":"import json, subprocess, sys\n\n\ndef measurement_stdout_is_json() -> bool:\n    proc = subprocess.run(\n        [sys.executable, \"scripts/measure-runtime-contract.py\"],\n        capture_output=True,\n        text=True,\n    )\n    if proc.returncode != 0:\n        return False\n    try:\n        json.loads(proc.stdout)\n        return True\n    except json.JSONDecodeError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    receipt = mod.run_measurement()\nexcept mod.RuntimeContractError as err:\n    if \"invalid JSON\" in str(err):\n        import json\n        proc = subprocess.run(\n            [sys.executable, \"scripts/measure-runtime-contract.py\"],\n            capture_output=True,\n            text=True,\n        )\n        try:\n            json.loads(proc.stdout)\n        except json.JSONDecodeError as e:\n            print(\"offending stdout near:\", repr(proc.stdout[max(0, e.pos - 80): e.pos + 80]))\n    raise SystemExit(2)","preventionTips":["Route all diagnostics in the measurement path to stderr (eprintln! / print(..., file=sys.stderr))","Keep cargo and build progress off the captured stdout pipe (cargo writes progress to stderr, wrappers may not)","Assert stdout purity in the measure script's own tests: parse your own output before exiting"],"tags":["python","json","subprocess","stdout","ci"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}