{"record":{"id":"94ac4f0f5876e431","repo":"Hmbown/CodeWhale","slug":"cargo-metadata-dependencies-for-dependent-must-be-a-list","errorCode":null,"errorMessage":"Cargo metadata dependencies for {dependent} must be a list","messagePattern":"Cargo metadata dependencies for (.+?) must be a list","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"scripts/release/validate-crate-publish-order.py","lineNumber":126,"sourceCode":"    missing = sorted(set(release_names) - ordered_set)\n    extra = sorted(ordered_set - set(release_names))\n    if missing or extra:\n        messages = []\n        if missing:\n            messages.append(\"publish package list is missing workspace crates: \" + \" \".join(missing))\n        if extra:\n            messages.append(\n                \"publish package list contains non-workspace crates: \" + \" \".join(extra)\n            )\n        raise ValidationError(\"\\n\".join(messages))\n\n    positions = {name: index for index, name in enumerate(ordered_crates)}\n    has_workspace_dependencies = {name: False for name in release_names}\n    publish_edges: set[tuple[str, str, str]] = set()\n    for dependent in release_names:\n        dependencies = workspace_by_name[dependent].get(\"dependencies\", [])\n        if not isinstance(dependencies, list):\n            raise ValidationError(f\"Cargo metadata dependencies for {dependent} must be a list\")\n        for dependency in dependencies:\n            if not isinstance(dependency, dict) or dependency.get(\"path\") is None:\n                continue\n            dependency_name = dependency.get(\"name\")\n            if dependency_name not in workspace_by_name:\n                continue\n            has_workspace_dependencies[dependent] = True\n            kind = dependency.get(\"kind\") or \"normal\"\n            # Cargo does not compile dev-dependencies while verifying a publish.\n            # They may legitimately point back across the publication DAG.\n            if kind == \"dev\":\n                continue\n            if dependency_name not in positions:\n                raise ValidationError(\n                    f\"{dependent} depends on workspace crate {dependency_name} \"\n                    f\"[{kind}], which is not in the codewhale-* release inventory\"\n                )\n            publish_edges.add((dependency_name, dependent, str(kind)))","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/release/validate-crate-publish-order.py#L108-L144","documentation":"The validator expects each package's `dependencies` entry in cargo metadata to be a JSON list. If it is not (malformed or unexpected metadata shape), graph construction cannot proceed and it throws naming the offending dependent crate.","triggerScenarios":"Feeding the script hand-edited or non-standard JSON instead of real `cargo metadata --format-version 1` output; a wrapper script transforming the metadata and coercing dependencies to an object/null.","commonSituations":"Custom tooling post-processes cargo metadata; piping output of a different cargo command by mistake; a Python script consuming a stale cached snapshot with mangled structure.","solutions":["Regenerate metadata with `cargo metadata --format-version 1 > metadata.json` and rerun.","Inspect workspace_by_name[dependent]['dependencies'] in the JSON to see the wrong shape.","Remove any custom transformation of the metadata before it reaches the validator.","Verify the script receives the file produced by the canonical cargo command, not a cached copy."],"exampleFix":"// before\n\"dependencies\": {\"codewhale-config\": {}}\n// after (cargo metadata format)\n\"dependencies\": [{\"name\": \"codewhale-config\", \"path\": \"...\"}]","handlingStrategy":"type-guard","validationCode":"deps = pkg.get('dependencies', [])\nif not isinstance(deps, list):\n    raise SystemExit(f'regenerate metadata: dependencies for {pkg[\"name\"]} is {type(deps).__name__}')","typeGuard":"def is_dep_list(v): return isinstance(v, list) and all(isinstance(d, dict) for d in v)","tryCatchPattern":"try:\n    validate_order(...)\nexcept ValidationError as e:\n    print('metadata shape error:', e)","preventionTips":["Always feed the script raw `cargo metadata --format-version 1` output","Do not cache or post-process metadata between generation and validation","Assert the metadata JSON schema in tooling before consumption"],"tags":["cargo","metadata","json","validation"],"backgroundTag":"unexpected-response-shape","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}