Hmbown/CodeWhale · error · RuntimeContractError
measurement top level must be an object
Error message
measurement top level must be an object
What it means
The measurement stdout parsed as valid JSON, but the top-level value is not an object (dict) - for example an array, a bare string, or a number. run_measurement() requires a top-level object because validate_receipt() navigates keys like document_kind and tool_catalog. Distinct from error 211, which covers stdout that is not JSON at all.
Source
Thrown at scripts/check-runtime-contract-budget.py:413
[sys.executable, str(MEASURE_SCRIPT)],
cwd=REPO_ROOT,
env=env,
capture_output=True,
text=True,
check=False,
)
sys.stderr.write(proc.stderr)
if proc.returncode != 0:
sys.stdout.write(proc.stdout)
raise RuntimeContractError(
f"runtime-contract measurement failed with exit code {proc.returncode}"
)
try:
receipt = json.loads(proc.stdout)
except json.JSONDecodeError as error:
raise RuntimeContractError(f"measurement emitted invalid JSON: {error}") from error
if not isinstance(receipt, dict):
raise RuntimeContractError("measurement top level must be an object")
validate_receipt(receipt)
return receipt
def update_command(receipt_path: Path | None, budget_path: Path) -> str:
parts = ["python3", "scripts/check-runtime-contract-budget.py"]
if receipt_path is not None:
parts.extend(["--receipt", str(receipt_path)])
if budget_path != BUDGET_PATH:
parts.extend(["--budget", str(budget_path)])
parts.append("--update")
return shlex.join(parts)
FRAGMENT_MODULE = REPO_ROOT / "crates" / "core" / "src" / "fragments.rs"
FRAGMENT_MAX_TOKENS_CEILING = 10_000
FRAGMENT_MAX_BYTES_CEILING = FRAGMENT_MAX_TOKENS_CEILING * 4
FRAGMENT_DEFAULT_MAX_BYTES_CEILING = 4 * 1024View on GitHub (pinned to 8880682c63)
Solutions
- Make the measure script print exactly one top-level JSON object and nothing else on stdout
- If you need multiple documents, wrap them in an object keyed by purpose rather than a top-level array
- Check the emitted shape first: python3 -c "import json,sys;print(type(json.load(sys.stdin)))" < out.json
Example fix
# before (scripts/measure-runtime-contract.py) print(json.dumps([receipt])) # after print(json.dumps(receipt))
Defensive patterns
Strategy: type-guard
Validate before calling
import json
def measurement_emits_object() -> bool:
proc = subprocess.run(
[sys.executable, "scripts/measure-runtime-contract.py"],
capture_output=True,
text=True,
)
if proc.returncode != 0:
return False
try:
return isinstance(json.loads(proc.stdout), dict)
except json.JSONDecodeError:
return False Type guard
import json
def parses_to_json_object(stdout: str) -> bool:
try:
return isinstance(json.loads(stdout), dict)
except json.JSONDecodeError:
return False Prevention
- Emit exactly one JSON object from the measure script and nothing else on stdout
- Do not wrap receipts in arrays or emit NDJSON on the measurement pipe
- When adding fields to the receipt, keep them inside the single top-level object and re-run the checker with --receipt
When it happens
Trigger: A measure script change that emits a list of receipts or a JSON scalar; a wrapper that outputs a JSON array of log lines; hand-fabricated measurement output for testing the checker.
Common situations: Refactoring measure-runtime-contract.py's serialization and accidentally wrapping the receipt in a list; piping through jq without the leading '.' selection; test harnesses that emit NDJSON (one object per line), which parses as error 211 unless wrapped in [...], and then fails here.
Related errors
- measurement emitted invalid JSON: {error}
- measurement receipt must be an object
- {kind} metric `{dotted}` must be a non-negative integer
- measurement emitted invalid JSON: {error}
- rss_during_delta_bytes is inconsistent
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/74abeca03f99212a.
Report an issue: GitHub.