Hmbown/CodeWhale · error · ValidationError
workspace packages have mixed versions
Error message
workspace packages have mixed versions: {rendered} What it means
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.
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.
Example fix
// before (crates/tui/Cargo.toml) version = "0.4.0" // others at 0.4.1 // after version = "0.4.1"
Defensive patterns
Strategy: validation
Validate before calling
import subprocess, json
meta = json.loads(subprocess.check_output(['cargo','metadata','--format-version','1']))
versions = {p['version'] for p in meta['packages']}
assert len(versions) == 1 and all(versions), f'mixed versions: {versions}' Try / catch
try:
validate_order(...)
except ValidationError as e:
print(e, file=sys.stderr); sys.exit(1) # message lists the conflicting versions Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Cargo metadata contains duplicate workspace package names
- cargo metadata failed with exit code
- Cargo metadata omits workspace package ids
- could not read Cargo metadata
- depends on workspace crate [ ], which is not in the…
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/b9d9a383d97a5fcf.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/release/validate-crate-publish-order.py:101
) -> tuple[str, dict[str, bool]]:
duplicate_crates = sorted(
{name for name in ordered_crates if ordered_crates.count(name) > 1}
)
if duplicate_crates:
raise ValidationError(
"publish package list contains duplicates: " + ", ".join(duplicate_crates)
)
names = [package.get("name") for package in packages]
if any(not isinstance(name, str) or not name for name in names):
raise ValidationError("workspace package is missing a name")
if len(set(names)) != len(names):
raise ValidationError("Cargo metadata contains duplicate workspace package names")
versions = sorted({package.get("version") for package in packages})
if len(versions) != 1 or not isinstance(versions[0], str) or not versions[0]:
rendered = ", ".join(str(version) for version in versions)
raise ValidationError(f"workspace packages have mixed versions: {rendered}")
workspace_by_name = {package["name"]: package for package in packages}
release_names = sorted(
name for name in workspace_by_name if name.startswith("codewhale-")
)
ordered_set = set(ordered_crates)
missing = sorted(set(release_names) - ordered_set)
extra = sorted(ordered_set - set(release_names))
if missing or extra:
messages = []
if missing:
messages.append("publish package list is missing workspace crates: " + " ".join(missing))
if extra:
messages.append(
"publish package list contains non-workspace crates: " + " ".join(extra)
)
raise ValidationError("\n".join(messages))
View on GitHub (pinned to 433685b202)