Skip to content

npm up -g fails on hidden directories in global node_modules #9298

@Grynn

Description

@Grynn

Is there an existing issue for this?

  • I have searched the existing issues

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions