Hmbown/CodeWhale · critical · ValidationError

crate publication order is not topological: {dependent} (p

Error message

crate publication order is not topological:
  {dependent} (position {positions[dependent] + 1}) depends on {dependency} (position {positions[dependency] + 1}) [{kind}]
Move every workspace dependency before its dependent in scripts/release/crates.sh.

What it means

The maintained publication order violates dependency topology: for at least one edge, the dependency sits at the same or a later 1-based position than the crate that depends on it (positions come from the index in the positional crates list). Publishing in that order fails crates.io verification because the dependency's version is not published yet. Each violation is listed with both positions and the dependency kind, and the fix location is named: scripts/release/crates.sh.

Source

Thrown at scripts/release/validate-crate-publish-order.py:166

            dependency,
            dependent,
            kind,
        )
        for dependency, dependent, kind in publish_edges
        if positions[dependency] >= positions[dependent]
    )
    if violations:
        lines = ["crate publication order is not topological:"]
        for dependency, dependent, kind in violations:
            lines.append(
                f"  {dependent} (position {positions[dependent] + 1}) depends on "
                f"{dependency} (position {positions[dependency] + 1}) [{kind}]"
            )
        lines.append(
            "Move every workspace dependency before its dependent in "
            "scripts/release/crates.sh."
        )
        raise ValidationError("\n".join(lines))

    return versions[0], has_workspace_dependencies


def main() -> int:
    args = parse_args()
    try:
        packages = workspace_packages(load_metadata(args.metadata_file))
        version, dependency_flags = validate_order(packages, args.crates)
    except ValidationError as error:
        print(error, file=sys.stderr)
        return 1

    print(f"version\t{version}\t")
    for name in sorted(dependency_flags):
        print(f"crate\t{name}\t{1 if dependency_flags[name] else 0}")
    return 0

View on GitHub (pinned to 8880682c63)

Solutions

  1. For every edge in the message, move the dependency crate above its dependent in scripts/release/crates.sh
  2. Re-run scripts/release/validate-crate-publish-order.py with the list to confirm the topology is clean
  3. Cross-check workspace deps when in doubt: cargo tree -p <dependent> -e normal,build

Example fix

# scripts/release/crates.sh: before (codewhale-tui depends on codewhale-release)
crates=(codewhale-protocol codewhale-tui codewhale-release codewhale-cli)

# after
crates=(codewhale-protocol codewhale-release codewhale-tui codewhale-cli)
Defensive patterns

Strategy: validation

Validate before calling

# Verify the order is topological before invoking the validator:
positions = {name: i for i, name in enumerate(ordered_crates)}
violations = [
    (dep, dependent)
    for dependent in release_names
    for dep in workspace_path_deps(dependent)   # names from cargo metadata, non-dev
    if positions.get(dep, -1) >= positions[dependent]
]
assert not violations, f"reorder crates.sh: {violations}"

Prevention

When it happens

Trigger: A newly added crate was appended to the end of the crates.sh list even though existing crates depend on it; entries were reordered during an edit; a dependency edge was introduced (crate A now path-depends on crate B) without moving B above A.

Common situations: Release validation after adding a mid-stack crate or after dependency restructuring between workspace crates.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/ee6edd93bb68aee4. Report an issue: GitHub.