npm Community Forum (Archive)

The npm community forum has been discontinued.

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

tgz file location resolution error

What I Wanted to Do

Install a local tgz package, which depends on another local tgz package.

What Happened Instead

Get “no such file or directory” error.

Reproduction Steps

I’ve packed a demo here.


In the above demo, local-pkg3 depends on local-pkg2, which depends on local-pkg1. Both local-pkg1 and local-pkg2 are packed as .tgz files. In local-pkg2's package.json file, the path to local-pkg1 is ../local-pkg1/local-pkg1-1.0.0.tgz, which is the valid relative path. But when installing local-pkg2 in local-pkg3, I get no such file or directory error for local-pkg1-1.0.0.tgz.

Errors in console:

npm ERR! path /private/tmp/bug/local-pkg2/local-pkg1/local-pkg1-1.0.0.tgz
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! syscall stat
npm ERR! enoent ENOENT: no such file or directory, stat '/private/tmp/bug/local-pkg2/local-pkg1/local-pkg1-1.0.0.tgz'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

Errors in npm log:

20 verbose stack Error: ENOENT: no such file or directory, stat '/private/tmp/bug/local-pkg2/local-pkg1/local-pkg1-1.0.0.tgz'
21 verbose cwd /private/tmp/bug/local-pkg3
22 verbose Darwin 18.2.0
23 verbose argv "/usr/local/Cellar/node@10/10.13.0/bin/node" "/usr/local/bin/npm" "i" "../local-pkg2/local-pkg2-1.0.0.tgz"
24 verbose node v10.13.0
25 verbose npm  v6.4.1
26 error path /private/tmp/bug/local-pkg2/local-pkg1/local-pkg1-1.0.0.tgz
27 error code ENOENT
28 error errno -2
29 error syscall stat
30 error enoent ENOENT: no such file or directory, stat '/private/tmp/bug/local-pkg2/local-pkg1/local-pkg1-1.0.0.tgz'
31 error enoent This is related to npm not being able to find a file.
32 verbose exit [ -2, true ]

Platform Info

$ npm --versions
$ node -p process.platform

Seems to be caused by unexpected (to me) Node.js path behaviour combined with no fix on npm’s side.

const path = require('path')

let where = '/home/user/pkg-2/2-1.0.0.tgz'
let spec = '../pkg-1/1-1.0.0.tgz'

path.resolve(where, spec) // /home/user/pkg-2/pkg-1/1-1.0.0.tgz

path can’t assume whether where is a file or a directory, so treats it as a directory. npm code doesn’t seem to account for that. I believe I have a fix, am writing tests now.

I made a PR to fix the where behaviour:

Note: with the fix it only works if the tgz file stays in the same place it was built. So, you’re probably better of putting any local dependencies in bundledDependencies.

Thanks for the quick response, this is what I figured. Did a local ad-hoc patch and it’s working as intended now, hope your PR gets merged soon.