Skip to content

[BUG] npm install --production can delete local workspaces if they've been renamed #8519

@jenseng

Description

@jenseng

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

Current Behavior

If you rename a local workspace package that's a dev dependency of another local workspace, and add it as a new dev dependency without removing the old one, this can cause lockfile/symlink cruft which can then cause --production installs to fully delete the local workspace directory.

Expected Behavior

Renaming a local workspace package should never cause --production installs to delete local workspaces. Ideally:

  • Obsolete local symlinks should be cleaned up, e.g. if bar gets renamed to baz, then node_modules/bar should get deleted.
  • Related to the above, depending on an obsolete local symlink (e.g. "dependencies": {"bar": "1.0.0"}) should cause an error.
  • Local workspaces should not have "dev": true set, even if they are dev deps of another workspace. This seems to get set when there are 2+ local symlinks for a package, and is likely what causes --production to delete things.

If any of the above are not feasible to implement, then npm ls or similar commands should alert users to these sorts of lockfile / tree inconsistencies.

Steps To Reproduce

Given

package.json

{
  "workspaces": ["workspaces/*"]
}

workspaces/foo/package.json

{
  "name": "foo",
  "version": "1.0.0",
  "private": true
}

workspaces/bar/package.json

{
  "name": "bar",
  "version": "1.0.0",
  "private": true
}

Run

  1. npm install --save-dev bar -w workspaces/foo
  2. Edit workspaces/bar/package.json and change the name to baz
  3. npm install --save-dev baz -w workspaces/foo

Alternatively, just check out this repo and run npm install which will get you to this point.

Observe

  • There are now symlinks at node_modules/bar and node_modules/baz
  • package-lock.json contains:
    "workspaces/bar": {
      "name": "baz",
      "version": "1.0.0",
      "dev": true
    },
  • npm ls reports no problems (though it does indicate it was dedup'ed)
  • npm install --production deletes workspaces/bar 💥

Additional Notes

  • This only happens with devDependencies
  • The lexicographical order of the old and new package names seems to matter. I.e. going from bar -> baz causes the issue. Going from baz -> bar does not; you still get two symlinks, but "dev": true won't get set in the lockfile, so a --production install won't delete the workspace.

Environment

  • npm: 11.5.2
  • Node.js: 22.14.0
  • OS Name: Mac OS Sequoia 15.6
  • System Model Name: Macbook Pro
  • npm config:
; copy and paste output from `npm config ls` here

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bugthing that needs fixingNeeds Triageneeds review for next steps

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions