{"record":{"id":"bf7a613933cef6b7","repo":"Hmbown/CodeWhale","slug":"cargo-metadata-root-must-be-an-object","errorCode":null,"errorMessage":"Cargo metadata root must be an object","messagePattern":"Cargo metadata root must be an object","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"scripts/release/validate-crate-publish-order.py","lineNumber":58,"sourceCode":"            [\"cargo\", \"metadata\", \"--locked\", \"--format-version\", \"1\", \"--no-deps\"],\n            check=False,\n            capture_output=True,\n            text=True,\n        )\n        if process.returncode != 0:\n            detail = process.stderr.strip()\n            suffix = f\": {detail}\" if detail else \"\"\n            raise ValidationError(\n                f\"cargo metadata failed with exit code {process.returncode}{suffix}\"\n            )\n        raw = process.stdout\n\n    try:\n        metadata = json.loads(raw)\n    except json.JSONDecodeError as error:\n        raise ValidationError(f\"Cargo metadata is not valid JSON: {error}\") from error\n    if not isinstance(metadata, dict):\n        raise ValidationError(\"Cargo metadata root must be an object\")\n    return metadata\n\n\ndef workspace_packages(metadata: dict[str, Any]) -> list[dict[str, Any]]:\n    members = metadata.get(\"workspace_members\")\n    packages = metadata.get(\"packages\")\n    if not isinstance(members, list) or not isinstance(packages, list):\n        raise ValidationError(\"Cargo metadata must contain workspace_members and packages lists\")\n\n    packages_by_id = {\n        package.get(\"id\"): package\n        for package in packages\n        if isinstance(package, dict) and isinstance(package.get(\"id\"), str)\n    }\n    missing_ids = [member for member in members if member not in packages_by_id]\n    if missing_ids:\n        raise ValidationError(\n            \"Cargo metadata omits workspace package ids: \" + \", \".join(missing_ids)","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/release/validate-crate-publish-order.py#L40-L76","documentation":"The metadata parsed as JSON but the root value is not an object (for example a top-level array or string). cargo metadata --format-version 1 always produces a root object, so this guard rejects structurally wrong input before the keys are read.","triggerScenarios":"A --metadata-file fixture containing only a projection such as the 'packages' array instead of the full metadata object; a JSON string or number at the root.","commonSituations":"Building test fixtures by extracting one field of cargo metadata output rather than saving the whole document.","solutions":["Replace the fixture with the complete cargo metadata document: cargo metadata --locked --format-version 1 --no-deps > <metadata-file>","If the fixture must be minimal, keep the root an object containing at least workspace_members and packages"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def is_cargo_metadata_root(value: object) -> bool:\n    return isinstance(value, dict)","tryCatchPattern":null,"preventionTips":["Never store a projection (e.g. just the packages array) as a metadata fixture; save the full document","Add a fixture test that asserts the root is an object with workspace_members and packages lists"],"tags":["json","validation","cargo","release","python"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}