Unhandled rejection Error: EISDIR: illegal operation on a directory, read


(Andreas Kohn) #1

What I Wanted to Do

Install a package from a .tar.gz file. By accident ended up with a directory with a .tgz extension, triggering the bug.

I expected npm to fail, reporting that the directory is not a package.

What Happened Instead

npm seems to get confused with this directory, and crashes.

Reproduction Steps

$ mkdir empty
$ cd empty
$ mkdir directory.tgz
$ npm install directory.tgz
Unhandled rejection Error: EISDIR: illegal operation on a directory, read8e26d59

npm ERR! cb() never called!

npm ERR! This is an error with npm itself. Please report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/andreas/.npm/_logs/2018-07-25T08_58_32_724Z-debug.log


2018-07-25T08_58_32_724Z-debug.log (523 Bytes)

Platform Info

$ npm -versions
{ '@collaborne/polaris-gateway': '1.7.8',
  npm: '5.6.0',
  ares: '1.10.1-DEV',
  cldr: '32.0',
  http_parser: '2.8.0',
  icu: '60.1',
  modules: '57',
  napi: '3',
  nghttp2: '1.29.0',
  node: '8.11.2',
  openssl: '1.0.2o',
  tz: '2017c',
  unicode: '10.0',
  uv: '1.19.1',
  v8: '6.2.414.54',
  zlib: '1.2.11' }
$ node -p process.platform

(Kat Marchán) #3

Triage note: this is a support issue. You can’t install directories like this.

(Andreas Kohn) #4

I’m not sure I understand your comment, so please bear with me for this clarification:

  1. According to npm-install documentation I can install folders by using npm install <folder> (https://docs.npmjs.com/cli/install)
  2. Having a folder name with a .tgz extension is allowed by the operating system

So I claim my expectation here is correct: npm should tell me that that directory isn’t a valid package to install, just like it would for any other empty folder:

$ mkdir folder
$ npm install ./folder
npm ERR! code ENOLOCAL
npm ERR! Could not install from "folder" as it does not contain a package.json file.

(Lars Willighagen) #5

So it seems that npm install directory.tgz/ (with the added slash /) does work, as a workaround. Basically, npm-package-arg checks file/directory names against a regex to determine which type they are:

res.type = isFilename.test(res.rawSpec) ? 'file' : 'directory'


And that regex doesn’t account for paths that are most likely tar archive files but are actually sneaky directories:

const isFilename = /[.](?:tgz|tar.gz|tar)$/i


And that regex matches ./directory.tgz as well. Changing that would probably involve fs calls, which would just be slowing everything down unnecessarily in most cases. Given that and that there’s a workaround, I think it’s fine to keep it this way.

(Kat Marchán) #6

that is correct. We look at filenames, as of npm@5, so the user would need to rename their directory. We have no intention of changing this :slight_smile:

(system) #7

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.