Is there an existing issue for this?
Current Behavior
npm up -g fails before updating any global packages when the global node_modules directory contains a hidden, dot-prefixed non-package directory.
Example failure from npm 10.9.7:
npm error code EINVALIDPACKAGENAME
npm error Invalid package name ".hidden-non-package" of package ".hidden-non-package@*": name cannot start with a period.
npm ls -g --depth=0 ignores the same hidden directory and only reports actual installed packages.
Expected Behavior
npm up -g should ignore hidden node_modules entries, matching Arborist loadActual behavior and npm's global package listing behavior. Hidden directories are not installed global packages and should not be converted into synthetic name@* update dependencies.
Steps To Reproduce
prefix="$(mktemp -d)"
npm_config_prefix="$prefix" npm install -g is-number@7.0.0
mkdir -p "$prefix/lib/node_modules/.hidden-non-package/node_modules"
npm_config_prefix="$prefix" npm ls -g --depth=0 --json
npm_config_prefix="$prefix" npm up -g
The npm ls -g command reports only is-number, but npm up -g fails with EINVALIDPACKAGENAME for .hidden-non-package@*.
Environment
- npm: 10.9.7
- Node.js: 22.22.2
- OS: Linux
Proposed Fix
In @npmcli/arborist, loadActual already filters hidden entries and retired scoped package folders with:
kids.filter(kid => !/^(@[^/]+\/)?\./.test(kid))
The global update path in buildIdealTree reads the global node_modules directory directly and queues every entry as a global update dependency. It should apply the same hidden-entry filter before adding tree.package.dependencies[name] = '*' or a file: link dependency.
I have a regression test and patch ready.
Is there an existing issue for this?
Current Behavior
npm up -gfails before updating any global packages when the globalnode_modulesdirectory contains a hidden, dot-prefixed non-package directory.Example failure from npm 10.9.7:
npm ls -g --depth=0ignores the same hidden directory and only reports actual installed packages.Expected Behavior
npm up -gshould ignore hiddennode_modulesentries, matching ArboristloadActualbehavior and npm's global package listing behavior. Hidden directories are not installed global packages and should not be converted into syntheticname@*update dependencies.Steps To Reproduce
The
npm ls -gcommand reports onlyis-number, butnpm up -gfails withEINVALIDPACKAGENAMEfor.hidden-non-package@*.Environment
Proposed Fix
In
@npmcli/arborist,loadActualalready filters hidden entries and retired scoped package folders with:The global update path in
buildIdealTreereads the globalnode_modulesdirectory directly and queues every entry as a global update dependency. It should apply the same hidden-entry filter before addingtree.package.dependencies[name] = '*'or afile:link dependency.I have a regression test and patch ready.