Hmbown/CodeWhale · error · ValidationError

Move every workspace dependency before its dependent in…

Error message

Move every workspace dependency before its dependent in scripts/release/crates.sh.

What it means

After collecting publish edges (dependency → dependent), the validator checks that in scripts/release/crates.sh every workspace dependency appears at an earlier position than each crate that depends on it, since crates.io publish order must follow the DAG. If any edge is out of order it raises an aggregated error listing each violation plus this instruction line.

Solutions

  1. Read each violation line: it names the edge and the current positions.
  2. Move the dependency earlier in the CRATES array in scripts/release/crates.sh so it precedes all dependents.
  3. Re-run the validator until no violations remain.
  4. For complex graphs, topologically sort the codewhale-* crates and regenerate the list.

Example fix

// before (crates.sh)
CRATES=(codewhale-tui codewhale-config)
// after
CRATES=(codewhale-config codewhale-tui)
Defensive patterns

Strategy: validation

Validate before calling

pos = {name: i for i, name in enumerate(crates_sh_list)}
for dep, dependent, _ in publish_edges:
    assert pos[dep] < pos[dependent], f'{dep} must precede {dependent}'

Try / catch

try:
    validate_order(...)
except ValidationError as e:
    print('order violations:\n' + str(e))  # each line names the misplaced edge

Prevention

When it happens

Trigger: Appending a new crate at the end of crates.sh when it is actually a dependency of an earlier crate; reordering crates.sh manually and placing a base crate after its consumer; a new dependency introduced between two already-listed crates.

Common situations: Release script maintenance where a new internal crate is added at the bottom of the list; alphabetical re-sorting of crates.sh ignoring dependency order.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/f2d49162dd00dafa. Report an issue: GitHub.

Appendix: 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 433685b202)