{"record":{"id":"2d71a888e667600c","repo":"Hmbown/CodeWhale","slug":"dependent-depends-on-workspace-crate-dependency-name-kind","errorCode":null,"errorMessage":"{dependent} depends on workspace crate {dependency_name} [{kind}], which is not in the codewhale-* release inventory","messagePattern":"(.+?) depends on workspace crate (.+?) \\[(.+?)\\], which is not in the codewhale-\\* release inventory","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"scripts/release/validate-crate-publish-order.py","lineNumber":140,"sourceCode":"    publish_edges: set[tuple[str, str, str]] = set()\n    for dependent in release_names:\n        dependencies = workspace_by_name[dependent].get(\"dependencies\", [])\n        if not isinstance(dependencies, list):\n            raise ValidationError(f\"Cargo metadata dependencies for {dependent} must be a list\")\n        for dependency in dependencies:\n            if not isinstance(dependency, dict) or dependency.get(\"path\") is None:\n                continue\n            dependency_name = dependency.get(\"name\")\n            if dependency_name not in workspace_by_name:\n                continue\n            has_workspace_dependencies[dependent] = True\n            kind = dependency.get(\"kind\") or \"normal\"\n            # Cargo does not compile dev-dependencies while verifying a publish.\n            # They may legitimately point back across the publication DAG.\n            if kind == \"dev\":\n                continue\n            if dependency_name not in positions:\n                raise ValidationError(\n                    f\"{dependent} depends on workspace crate {dependency_name} \"\n                    f\"[{kind}], which is not in the codewhale-* release inventory\"\n                )\n            publish_edges.add((dependency_name, dependent, str(kind)))\n\n    violations = sorted(\n        (\n            dependency,\n            dependent,\n            kind,\n        )\n        for dependency, dependent, kind in publish_edges\n        if positions[dependency] >= positions[dependent]\n    )\n    if violations:\n        lines = [\"crate publication order is not topological:\"]\n        for dependency, dependent, kind in violations:\n            lines.append(","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/release/validate-crate-publish-order.py#L122-L158","documentation":"For every non-dev (normal/build/etc.) path dependency a codewhale-* crate has on another workspace crate, that dependency must also appear in the codewhale-* publish inventory (crates.sh), since it must be published too and before its dependent. Dev-dependencies are skipped because Cargo does not compile them during publish verification. If a required dependency is missing from the inventory, this error names the dependent, the dependency, and the dependency kind.","triggerScenarios":"A crate gains a new normal path dependency on a workspace crate whose name does not start with codewhale-* (so it is not in release_names), or on a workspace crate excluded from the publish list; a crate is renamed so it drops out of the inventory.","commonSituations":"Adding an internal helper crate without the codewhale- prefix; converting a dev-dependency to a normal dependency (now it becomes a publish edge); introducing a private crate not intended for publishing but depended on by a published one.","solutions":["Rename the dependency crate to the codewhale-* convention and add it to scripts/release/crates.sh before its dependents.","Or vendor/inline the helper code to remove the cross-crate dependency.","Or, if the dependency must not be published, restructure so the published crate does not depend on it (e.g. move shared code into a published crate).","If the edge is test-only, declare it as a dev-dependency (validator skips those)."],"exampleFix":"// before (crates/tui/Cargo.toml)\n[dependencies]\nmy-helper = { path = \"../my-helper\" }\n// after\n[dev-dependencies]\nmy-helper = { path = \"../my-helper\" }  # or rename to codewhale-* and add to crates.sh","handlingStrategy":"validation","validationCode":"for dep in dependent_pkg['dependencies']:\n    if dep.get('kind') in (None, 'normal', 'build') and dep.get('path') \\\n       and dep['name'] in workspace and dep['name'] not in ordered:\n        print('add to crates.sh:', dep['name'])","typeGuard":null,"tryCatchPattern":"try:\n    validate_order(...)\nexcept ValidationError as e:\n    print('publish inventory gap:', e)","preventionTips":["Prefix every published internal crate with codewhale-","Prefer dev-dependencies for test-only cross-crate edges","Run the validator in CI on every dependency-affecting change"],"tags":["cargo","publish","dependency-graph","release"],"backgroundTag":"missing-dependency","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"}