Skip to content

fix(arborist): remove stale .bin shims after uninstall under linked - #9643

Merged
owlstronaut merged 1 commit into
release/v11from
backport/v11/9632
Jun 24, 2026
Merged

fix(arborist): remove stale .bin shims after uninstall under linked#9643
owlstronaut merged 1 commit into
release/v11from
backport/v11/9632

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Backport of #9632 to release/v11.

…9632)

In continuation of our exploration of using `install-strategy=linked` in
the [Gutenberg
monorepo](WordPress/gutenberg#75814), which
powers the WordPress Block Editor.

Under `install-strategy=linked`, `npm uninstall <pkg>` removed the
package's top-level symlink and its `.store` entry but left its shim in
`node_modules/.bin` behind as a dangling link. The leftover shim can
break tools that enumerate `node_modules/.bin`, shadow a later-installed
binary of the same name, and is not healed by a subsequent `npm
install`.

## Why

A linked reify builds the actual tree for the diff from the ideal tree
(`#buildLinkedActualForDiff`), so a removed dependency is never compared
against what is on disk and the diff emits no action to drop its bin
shim. The top-level symlink and store entry are already cleaned by the
post-reify sweep, but bin shims were not covered by it.

## How

`reify.js` `#cleanOrphanedStoreEntries` now also builds `binsByDir`:
while collecting the valid top-level links per `node_modules` directory,
it records the bin names each still-linked package provides from
`child.package.bin`. The new `#cleanStaleBinLinks` then removes any
`.bin` entry whose base name (after stripping a `.cmd`/`.ps1` suffix) is
not provided by a surviving package, or which is a dangling symlink.
Matching by name keeps the check cross-platform across POSIX symlink
shims and Windows `.cmd`/`.ps1` shim files, and reuses data already in
the ideal tree without adding a dependency. Shims for packages that
survive the uninstall are preserved.

## References

Fixes #9613

(cherry picked from commit 981e249)
@owlstronaut
owlstronaut merged commit 9d1774e into release/v11 Jun 24, 2026
33 checks passed
@owlstronaut
owlstronaut deleted the backport/v11/9632 branch June 24, 2026 18:21
@github-actions github-actions Bot mentioned this pull request Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants