npm Community Forum (Archive)

The npm community forum has been discontinued.

To discuss usage of npm, visit the GitHub Support Community.

ENOENT error when the same package appears in local dependencies

What I Wanted to Do

Running npm install and expecting packages to be installed.

Cloning the git repo below will help to understand the issue.
As you can see there, a project has 3 directories (comp-a, comp-b and comp-c), each one is a package, all have the same package dependency (classnames but can be anything).
In addition, the first package (comp-a) has the other two packages as dependencies with relative paths.
The second package (comp-b) has the last package (comp-c) as a dependency with a relative path.

What Happened Instead

Got the following error

➜  comp-a npm i
npm WARN rollback Rolling back classnames@2.2.6 failed (this is probably harmless): /private/tmp/npm-issue/components/comp-c/node_modules/classnames is not a child of /private/tmp/npm-issue/components/comp-a
npm WARN comp-a@1.0.0 No description
npm WARN comp-a@1.0.0 No repository field.

npm ERR! code ENOENT
npm ERR! syscall rename
npm ERR! path /private/tmp/npm-issue/components/comp-a/node_modules/.staging/classnames-00a850cf
npm ERR! dest /private/tmp/npm-issue/components/comp-c/node_modules/classnames
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, rename '/private/tmp/npm-issue/components/comp-a/node_modules/.staging/classnames-00a850cf' -> '/private/tmp/npm-issue/components/comp-c/node_modules/classnames'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/davidfirst/.npm/_logs/2019-09-17T16_13_15_580Z-debug.log
➜  comp-a

Reproduction Steps

  1. git clone
  2. cd npm-reproducible-bug/components/comp-a
  3. npm install


npm-debug.log file is inside the same git repo:

Investigating the log file, it seems like that NPM installs classmate package on a temp dir, then, it creates the exact same temp-dir multiple times, because in the project this package is required from multiple packages. Then, once done, it changes the temp-dir to classmate, however, since it does it multiple times, it tries to change it again from temp-dir to classmate and failed because the temp-dir doesn’t exist anymore.

Platform Info

$ npm --versions
{ 'comp-a': '1.0.0',
  npm: '6.11.3',
  ares: '1.10.1-DEV',
  cldr: '32.0',
  http_parser: '2.8.0',
  icu: '60.1',
  modules: '57',
  napi: '3',
  nghttp2: '1.32.0',
  node: '8.12.0',
  openssl: '1.0.2p',
  tz: '2017c',
  unicode: '10.0',
  uv: '1.19.2',
  v8: '6.2.414.66',
  zlib: '1.2.11' }
$ node -p process.platform

I added an automated test based on the example repo:

Thanks for the analysis and reproduction case! This is helpful.

Unfortunately, looking at the code, two things seem clear: first, you are correct, this has been broken since version 5.0.0. Second, it’s unlikely to be fixable before version 7.0.0. The changes required, while not in themselves breaking changes per se, will involve a lot of refactoring work of some components that are already being rewritten for v7.

I’ll add it to the list of cases that Arborist should handle properly, and ensure it gets in for v7.

Thanks a lot for the quick response! Sounds like the options are: