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

  1. Regenerate the full cargo metadata JSON object (do not save only sub-fields): cargo metadata --locked --format-version 1 --no-deps
  2. Omit the file argument to let the script obtain metadata itself
  3. Inspect the first characters of the file — it must start with '{'
  4. 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

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


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)