Skip to content

npm target: workspace: dependencies break auto version bumping and break published tarballs #804

@BYK

Description

@BYK

Summary

Two related issues with npm workspace support in craft's npm target when the monorepo uses workspace:* dependency specifiers (the canonical form for npm/yarn/bun workspaces):

Issue 1: npm version --workspaces fails on workspace:* deps

Craft's auto-bump (NpmTarget.bumpVersion) runs:

npm version <NEW_VERSION> --no-git-tag-version --allow-same-version --workspaces --include-workspace-root

When workspace packages declare deps on each other as "@scope/pkg": "workspace:*", this fails with:

npm error code EUNSUPPORTEDPROTOCOL
npm error Unsupported URL Type "workspace:": workspace:*

and exits code 1. Craft treats this as failure and falls back to per-package npm version — which hits the same error in each subdir and fails the whole release.

The confusing part: npm does successfully bump the version field in every package.json before erroring. It only errors after the bumps land on disk, while it's validating dep URLs. So the files are in the right state — craft just can't tell from the exit code.

This is npm/cli#8845 — known and unresolved upstream. workspace: is documented as supported but npm 11.x's validator still rejects it during the version command.

Workarounds craft could pick up:

  • Treat EUNSUPPORTEDPROTOCOL on workspace: specifically as a warning rather than failure, since the bump itself already happened
  • Or: edit each package.json directly via jq/awk rather than going through npm at all
  • Or: detect workspace: deps and use a different bump path

Issue 2: bun.lock workspace versions remain stale after bump

Separately: when a repo uses bun.lock (Bun workspace monorepos), bun pm pack rewrites workspace:* specifiers to concrete versions at pack time. It reads those versions from bun.lock, not from the workspace package.json.

Neither npm version nor bun install updates the lockfile's workspace version entries. bun install --lockfile-only on a stale lockfile leaves the workspace version untouched — the only reliable way to refresh is rm bun.lock && bun install --lockfile-only.

Consequence: if the release pipeline publishes tarballs via bun pm pack, the published dependencies field still points at the OLD workspace version that no longer exists on the registry. Install fails with ETARGET No matching version found for @scope/pkg@OLD_VERSION.

We hit this on our first release: @loreai/opencode@0.10.0 and @loreai/pi@0.10.0 shipped with "@loreai/core": "0.9.1" deps (0.9.1 was the lockfile's recorded version), but we'd bumped to 0.10.0 and never published 0.9.1.

This one's more Bun-specific, but since craft is already workspace-aware and some monorepos use Bun, it might be worth either:

  • Detecting bun.lock and refreshing workspace entries after bump
  • Documenting that the bump doesn't touch bun.lock and users need their own step

Environment

  • craft 2.26.0 (most recent)
  • npm 11.6.2
  • Node 24
  • Bun 1.3.11

Our workaround (for reference)

We replaced craft's auto-bump with a preReleaseCommand script that:

  1. Uses jq to rewrite the version field in each workspace package.json
  2. Uses awk to rewrite the version field of workspace entries inside bun.lock

Source: https://github.com/BYK/loreai/blob/main/scripts/bump-version.sh

Suggested next step

For Issue 1 alone, the smallest craft-side fix would be: when npm version --workspaces exits non-zero, check whether the package.json files actually got bumped. If yes, log a warning about EUNSUPPORTEDPROTOCOL and proceed; if no, fail as today.

For Issue 2, a lockfile-refresh step would be nice-to-have but it's reasonable to say "use a preReleaseCommand if you're on bun".

Happy to send a PR if the approach sounds right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions