{"record":{"id":"b9d9a383d97a5fcf","repo":"Hmbown/CodeWhale","slug":"workspace-packages-have-mixed-versions-rendered","errorCode":null,"errorMessage":"workspace packages have mixed versions: {rendered}","messagePattern":"workspace packages have mixed versions: (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"scripts/release/validate-crate-publish-order.py","lineNumber":101,"sourceCode":") -> 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:\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","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/release/validate-crate-publish-order.py#L83-L119","documentation":"The release process requires all workspace crates to share a single version. After collecting the distinct versions from cargo metadata, if there is more than one (or the single version is missing/empty), the validator throws with the rendered list of conflicting versions so the developer can see exactly which versions disagree.","triggerScenarios":"Bumping the version of one crate (or forgetting to bump the rest) before running scripts/release/validate-crate-publish-order.py; a crate with a missing or empty `version` field in its Cargo.toml.","commonSituations":"Manual version edits during a release cut instead of using the release script; a merge that took one side of a version bump; a newly added workspace crate created from a template with version 0.0.0.","solutions":["Read the rendered versions in the error and find which crates disagree (grep each Cargo.toml for `version`).","Bump/align every workspace crate's [package].version to the same value (use the repo's version-bump/release script if present).","Check for merge-conflict leftovers like `<<<<<<<` in a Cargo.toml version line.","Re-run `cargo metadata` and the validator to confirm a single version."],"exampleFix":"// before (crates/tui/Cargo.toml)\nversion = \"0.4.0\"  // others at 0.4.1\n// after\nversion = \"0.4.1\"","handlingStrategy":"validation","validationCode":"import subprocess, json\nmeta = json.loads(subprocess.check_output(['cargo','metadata','--format-version','1']))\nversions = {p['version'] for p in meta['packages']}\nassert len(versions) == 1 and all(versions), f'mixed versions: {versions}'","typeGuard":null,"tryCatchPattern":"try:\n    validate_order(...)\nexcept ValidationError as e:\n    print(e, file=sys.stderr); sys.exit(1)  # message lists the conflicting versions","preventionTips":["Always bump versions via the release script, not manual edits","Run the version validator as a pre-release CI gate","After merges, diff all Cargo.toml version lines before releasing"],"tags":["cargo","versioning","release","workspace"],"backgroundTag":"conflicting-config-options","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"}