{"record":{"id":"f03846b9aeb7fd40","repo":"Hmbown/CodeWhale","slug":"workspace-package-is-missing-a-name","errorCode":null,"errorMessage":"workspace package is missing a name","messagePattern":"workspace package is missing a name","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"scripts/release/validate-crate-publish-order.py","lineNumber":94,"sourceCode":"            \"Cargo metadata omits workspace package ids: \" + \", \".join(missing_ids)\n        )\n    return [packages_by_id[member] for member in members]\n\n\ndef validate_order(\n    packages: list[dict[str, Any]], ordered_crates: list[str]\n) -> tuple[str, dict[str, bool]]:\n    duplicate_crates = sorted(\n        {name for name in ordered_crates if ordered_crates.count(name) > 1}\n    )\n    if duplicate_crates:\n        raise ValidationError(\n            \"publish package list contains duplicates: \" + \", \".join(duplicate_crates)\n        )\n\n    names = [package.get(\"name\") for package in packages]\n    if any(not isinstance(name, str) or not name for name in names):\n        raise ValidationError(\"workspace package is missing a name\")\n    if len(set(names)) != len(names):\n        raise ValidationError(\"Cargo metadata contains duplicate workspace package names\")\n\n    versions = sorted({package.get(\"version\") for package in packages})\n    if len(versions) != 1 or not isinstance(versions[0], str) or not versions[0]:\n        rendered = \", \".join(str(version) for version in versions)\n        raise ValidationError(f\"workspace packages have mixed versions: {rendered}\")\n\n    workspace_by_name = {package[\"name\"]: package for package in packages}\n    release_names = sorted(\n        name for name in workspace_by_name if name.startswith(\"codewhale-\")\n    )\n    ordered_set = set(ordered_crates)\n    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:","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/release/validate-crate-publish-order.py#L76-L112","documentation":"validate_order extracts each workspace package's 'name' and raises this ValidationError if any package lacks a non-empty string name. Without names, crates cannot be matched against the ordered publish list.","triggerScenarios":"A package entry in cargo metadata has no 'name' field or an empty/None name — only possible with malformed, hand-edited, or mocked metadata, since real cargo metadata always includes names.","commonSituations":"Hand-trimmed metadata files that dropped the name key; test fixtures built incorrectly; a tool version or transformation step that renamed/removed the field.","solutions":["Regenerate metadata with cargo metadata --locked --format-version 1 --no-deps so every package has a name","Fix the fixture/transformation step that strips or renames the 'name' field","Ensure each workspace member's Cargo.toml defines a non-empty [package] name","Validate the metadata file with jq/python before running the validator"],"exampleFix":"// before (trimmed entry)\n{\"id\": \"x\", \"version\": \"0.1.0\"}\n// after\n{\"id\": \"x\", \"name\": \"codewhale-core\", \"version\": \"0.1.0\"}","handlingStrategy":"validation","validationCode":"import json\nm = json.load(open(\"cargo-metadata.json\"))\nbad = [p for p in m.get(\"packages\", []) if not isinstance(p.get(\"name\"), str) or not p.get(\"name\")]\nif bad:\n    raise SystemExit(f\"packages missing names: {len(bad)}; regenerate metadata\")","typeGuard":"def has_name(p) -> bool:\n    return isinstance(p, dict) and isinstance(p.get(\"name\"), str) and bool(p[\"name\"])","tryCatchPattern":"try:\n    validate_publish_order(metadata_file)\nexcept ValidationError as e:\n    if \"missing a name\" in str(e):\n        print(\"metadata entries lack 'name'; use unmodified cargo metadata output\")","preventionTips":["Never strip fields when post-processing metadata JSON","Validate fixtures against the real cargo metadata schema before use","Each workspace member's Cargo.toml must define a non-empty package name"],"tags":["python","cargo","validation","metadata"],"backgroundTag":"missing-required-config-field","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"}