Hmbown/CodeWhale · error · ValidationError

cargo metadata failed with exit code {process.returncode}{su

Error message

cargo metadata failed with exit code {process.returncode}{suffix}

What it means

The validator shells out to 'cargo metadata --locked --format-version 1 --no-deps' and that subprocess exited non-zero. The workspace inventory (names, versions, path dependencies) is derived from this metadata, so any cargo failure is fatal; the message embeds the exit code and the stripped stderr detail when present.

Source

Thrown at scripts/release/validate-crate-publish-order.py:48


def load_metadata(metadata_file: Path | None) -> dict[str, Any]:
    if metadata_file is not None:
        try:
            raw = metadata_file.read_text(encoding="utf-8")
        except OSError as error:
            raise ValidationError(f"could not read Cargo metadata: {error}") from error
    else:
        process = subprocess.run(
            ["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")

View on GitHub (pinned to 8880682c63)

Solutions

  1. Reproduce and read the real error: cargo metadata --locked --format-version 1 --no-deps
  2. If the complaint is lockfile drift, refresh it (e.g. cargo update -w or any build) and commit Cargo.lock
  3. Fix the manifest error cargo names (parse error, missing field, bad version requirement)
  4. Confirm cargo works at all in this environment: cargo --version
Defensive patterns

Strategy: validation

Validate before calling

# Pre-flight the exact metadata query before the release run:
import subprocess, sys

probe = subprocess.run(
    ["cargo", "metadata", "--locked", "--format-version", "1", "--no-deps"],
    capture_output=True, text=True,
)
if probe.returncode != 0:
    sys.exit(f"fix cargo first: {probe.stderr.strip()}")

Try / catch

try:
    metadata = load_metadata(args.metadata_file)
except ValidationError as e:
    print(f"release validation aborted: {e}", file=sys.stderr)
    sys.exit(1)

Prevention

When it happens

Trigger: Cargo.lock is out of date with the manifests while --locked forbids regeneration; a workspace member's Cargo.toml has a syntax or resolution error; a renamed/removed crate leaves stale references; cargo itself fails to start in the environment.

Common situations: Editing dependencies or adding a crate without running a build to refresh Cargo.lock; switching toolchains; a merge that combined manifest changes but not lockfile changes.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/a4ed31a3d88ab4f8. Report an issue: GitHub.