Hmbown/CodeWhale · error · ValidationError
Cargo metadata root must be an object
Error message
Cargo metadata root must be an object
What it means
After JSON parsing succeeds, load_metadata checks that the decoded cargo metadata is a dict (JSON object) and raises this ValidationError otherwise. cargo metadata is specified to emit a top-level object, so anything else indicates a corrupt or substituted input.
Solutions
- Regenerate the full cargo metadata JSON object (do not save only sub-fields): cargo metadata --locked --format-version 1 --no-deps
- Omit the file argument to let the script obtain metadata itself
- Inspect the first characters of the file — it must start with '{'
- Fix the pipeline step that produces the file to write the complete object
Example fix
// before (fragment saved) json.dump(metadata["packages"], f) // after json.dump(metadata, f) # full cargo metadata object
Defensive patterns
Strategy: validation
Validate before calling
import json
m = json.load(open("cargo-metadata.json"))
if not isinstance(m, dict):
raise SystemExit("metadata must be a top-level JSON object; save full cargo metadata output") Type guard
def is_cargo_metadata(value) -> bool:
return isinstance(value, dict) Try / catch
try:
validate_publish_order(metadata_file)
except ValidationError as e:
if "root must be an object" in str(e):
print("the file is a JSON fragment; write the full metadata object") Prevention
- Never save sub-objects (e.g. only packages) as the metadata artifact
- Assert the artifact starts with '{' in pipeline steps that produce it
- Validate fixtures against the real cargo metadata shape
When it happens
Trigger: The metadata file contains a JSON array, string, number, or null instead of an object — e.g. someone stored just the packages list, or a pipeline step wrote `[]` on empty output.
Common situations: A downstream script extracted metadata['packages'] and saved only that fragment; a mock/test fixture file with the wrong shape; an empty-output placeholder written by a failed step.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Cargo metadata must contain workspace_members and packages…
- Cargo metadata dependencies for
- Cargo metadata is not valid JSON
- Cargo metadata omits workspace package ids
- invalid : top level must be an object
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/bf7a613933cef6b7.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/release/validate-crate-publish-order.py:58
["cargo", "metadata", "--locked", "--format-version", "1", "--no-deps"],
check=False,
capture_output=True,
text=True,
)
if process.returncode != 0:
detail = process.stderr.strip()
suffix = f": {detail}" if detail else ""
raise ValidationError(
f"cargo metadata failed with exit code {process.returncode}{suffix}"
)
raw = process.stdout
try:
metadata = json.loads(raw)
except json.JSONDecodeError as error:
raise ValidationError(f"Cargo metadata is not valid JSON: {error}") from error
if not isinstance(metadata, dict):
raise ValidationError("Cargo metadata root must be an object")
return metadata
def workspace_packages(metadata: dict[str, Any]) -> list[dict[str, Any]]:
members = metadata.get("workspace_members")
packages = metadata.get("packages")
if not isinstance(members, list) or not isinstance(packages, list):
raise ValidationError("Cargo metadata must contain workspace_members and packages lists")
packages_by_id = {
package.get("id"): package
for package in packages
if isinstance(package, dict) and isinstance(package.get("id"), str)
}
missing_ids = [member for member in members if member not in packages_by_id]
if missing_ids:
raise ValidationError(
"Cargo metadata omits workspace package ids: " + ", ".join(missing_ids)View on GitHub (pinned to 433685b202)