Hmbown/CodeWhale · error · PersistenceBacklogError
measurement emitted invalid JSON: {error}
Error message
measurement emitted invalid JSON: {error} What it means
The measurement subprocess exited 0 but its stdout was not parseable as JSON. The checker requires the child to print exactly one JSON receipt on stdout and nothing else, so any stray byte breaks parsing. The appended JSONDecodeError detail (line/column) tells you where stdout stops being valid JSON.
Source
Thrown at scripts/check-persistence-backlog-budget.py:390
def measure() -> dict[str, Any]:
env = os.environ.copy()
env["CARGO_NET_OFFLINE"] = "true"
result = subprocess.run(
[sys.executable, str(MEASURE_SCRIPT)],
cwd=ROOT,
env=env,
text=True,
capture_output=True,
check=False,
)
sys.stderr.write(result.stderr)
if result.returncode != 0:
sys.stdout.write(result.stdout)
raise PersistenceBacklogError("measurement command failed")
try:
receipt = json.loads(result.stdout)
except json.JSONDecodeError as error:
raise PersistenceBacklogError(f"measurement emitted invalid JSON: {error}") from error
if not isinstance(receipt, dict):
raise PersistenceBacklogError("measurement receipt must be an object")
return receipt
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--receipt", type=Path, help="check an existing receipt")
parser.add_argument("--budget", type=Path, default=BUDGET_PATH)
args = parser.parse_args()
try:
expected_source = current_source_identity()
receipt = load_json(args.receipt, "receipt") if args.receipt else measure()
budget = load_json(args.budget, "budget")
baseline_receipt = load_json(BASELINE_RECEIPT_PATH, "baseline receipt")
validate_baseline_receipt(budget, baseline_receipt)
increases, decreases = compare(
receipt,View on GitHub (pinned to 8880682c63)
Solutions
- Run `python3 scripts/measure-persistence-backlog.py` and inspect stdout to find the non-JSON bytes
- Move any print/log statements in the measure script to stderr
- Redirect build and toolchain output to stderr inside the measure script
- Confirm purity with `python3 scripts/measure-persistence-backlog.py | python3 -m json.tool`
Example fix
# before (measure-persistence-backlog.py)
print("measuring...")
sys.stdout.write(json.dumps(receipt))
# after
print("measuring...", file=sys.stderr)
sys.stdout.write(json.dumps(receipt)) Defensive patterns
Strategy: try-catch
Validate before calling
out = subprocess.run([sys.executable, str(MEASURE_SCRIPT)], capture_output=True, text=True, check=False).stdout json.loads(out) # dry-run parse before wiring the child into the checker
Try / catch
try:
receipt = json.loads(result.stdout)
except json.JSONDecodeError as e:
show_stdout_context(result.stdout, e)
raise Prevention
- Print diagnostics only to stderr in measure scripts
- Pipe child stdout through python3 -m json.tool while developing
- Keep a unit test asserting the measure script's stdout parses as a JSON object
When it happens
Trigger: A debug `print()` added to measure-persistence-backlog.py; cargo or rustc diagnostics routed to stdout; ANSI codes or log lines prepended to the receipt; output truncated mid-write.
Common situations: Temporary instrumentation added to the measure script without `file=sys.stderr`; a dependency printing to stdout on first run; platform differences in child-process output handling.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- measurement emitted invalid JSON: {error}
- measurement receipt must be an object
- measurement top level must be an object
- Codewhale stream-json line {line_number} was not valid JSON
- rss_during_delta_bytes is inconsistent
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/d42b4e7c4549098c.
Report an issue: GitHub.