Hmbown/CodeWhale · error · RuntimeContractError
invalid {kind} {path}: top level must be an object
Error message
invalid {kind} {path}: top level must be an object What it means
The JSON file parsed successfully but its top level is not an object — the checker requires a dict to hold document_kind, schema_version, and the metric tree. A top-level array, string, or number fails immediately before any field validation runs. This guards the document shape at the earliest possible point.
Source
Thrown at scripts/check-runtime-contract-budget.py:167
)
for stage, label in REPRESENTATIVE_STAGES
),
)
class RuntimeContractError(ValueError):
"""A receipt or budget is missing a required, well-typed metric."""
def load_json(path: Path, kind: str) -> dict[str, Any]:
try:
document = json.loads(path.read_text(encoding="utf-8"))
except FileNotFoundError as error:
raise RuntimeContractError(f"missing {kind}: {path}") from error
except (OSError, json.JSONDecodeError) as error:
raise RuntimeContractError(f"invalid {kind} {path}: {error}") from error
if not isinstance(document, dict):
raise RuntimeContractError(f"invalid {kind} {path}: top level must be an object")
return document
def validate_document(
document: dict[str, Any], expected_kind: str, source: str
) -> None:
actual_kind = document.get("document_kind")
if actual_kind != expected_kind:
raise RuntimeContractError(
f"{source} document_kind must be `{expected_kind}`, got {actual_kind!r}"
)
version = document.get("schema_version")
if (
isinstance(version, bool)
or not isinstance(version, int)
or version != SCHEMA_VERSION
):
raise RuntimeContractError(View on GitHub (pinned to 8880682c63)
Solutions
- Open the file and confirm it starts with `{`; if it is an array, extract the single relevant object
- Regenerate the file with scripts/measure-runtime-contract.py rather than hand-assembling it
- Pass one file per document to --receipt
Example fix
// before — file contains a top-level array
[ { "document_kind": "codewhale.runtime_contract_receipt", ... } ]
// after
{ "document_kind": "codewhale.runtime_contract_receipt", ... } Defensive patterns
Strategy: type-guard
Validate before calling
doc = json.loads(text)
assert isinstance(doc, dict), f'top level must be an object, got {type(doc).__name__}' Type guard
def is_contract_document(value):
return isinstance(value, dict) and isinstance(value.get('document_kind'), str) Prevention
- Store one JSON object per file
- Regenerate documents with the measure script rather than hand-assembling
- Guard the top-level type in any tooling that writes receipts
When it happens
Trigger: Wrapping receipts in a JSON array (for example multi-platform bundles); storing a bare string; saving a JSON fragment instead of the full document.
Common situations: Collecting receipts from several CI lanes into one file; tooling that emits arrays by default.
Related errors
- baseline provenance build profile/sample count changed
- measurement receipt must be an object
- invalid {kind} {path}: {error}
- {source} document_kind must be `{expected_kind}`, got {actua
- {kind} is missing required field `{dotted}`
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/c2609820ae61b57a.
Report an issue: GitHub.