Solution to the EISDIR connundrum

Every day I see one or two people reporting the same EISDIR error when trying to install a package globally. See this as an example.

The argument for installing global packages is one I’d like to avoid, but it seems like the standard is moving towards using something like a node version manager (nvm) to manage your nvm versions, and then maintaining package dependencies inside each project, and referencing whatever you need to run from those packages with npm scripts or actual code itself. Isn’t this the intended use case?

The node version managers are separate from npm, Inc., so that may be problematic seeing that support may dwindle in the future, but they are open source, so they could be forked and maintained under the npm umbrella if those communities cease to support such technologies.

I think the logging is fine. The EISDIR is self-explanatory in my opinion, but the root cause is not always the same.

Wrapping up, seeing the EISDIR error reporting trend in the “support” tag gave rise to this idea, and I thought it’d be worth sharing with the community.

Let me know your thoughts!

Thanks,
Brian

I’ve seen two main categories, EISDIR in .staging and EISDIR in _cacache. Correct me if I’m wrong though, there might be different causes for each of those. We probably want canonical topics for both to link to. I suggest the following, since they’re the first topics in #bugs for the respective categories.

1 Like

Hmm, I guess they’re both the same after all. Also, thanks @shadowspawn for your work on this!

1 Like

I think I’m moving this to #development because it isn’t a feature request (I hope), we have enough #bugs posts already, and this is probably more of an implementation thing anyway. We still have around 2 posts about this per day, and that’s just the people who don’t look/find the dozens of pre-existing posts — imagine the actual number of people encountering this. Again, shout-out to @shadowspawn for handling most, if not all of them.

@zkat, not sure if I should ping you specifically here, but I was wondering if this is being tracked internally already, or if this is left up to community contributors.

1 Like

I’ve taken a look, and frankly, I have no idea why this is happening. I tried to go into cacache and suss it out, but this error just doesn’t make sense, and it almost makes me wonder if it’s a node bug, but that’d be weird. I’d love some help with it, and I think it’s fine to move this to #development.

2 Likes

Update: @godmar tracked down possible source of problem: https://github.com/zkat/pacote/issues/174

What I found is related only to the phenomenon of leaving root.root owned directories in ~/.npm/_cacache, but since @zkat was wondering, here’s how to track this down:
I simply added

if (uid === undefined)
   console.trace();

to both fixOwner and mkdirfix in cacache's lib/util/fix-owner.js here. When running as sudo, the backtraces pointed immediately at the culprit.

I’m revising this post (you can use the history for the original version). I had originally suggested to add an unhandledRejection handler; upon closer investigation, however, it turns out that the default handler prints out the same information a custom handler would.

The reason the errors in the rejected promises lack stack traces appears to be bluebird.
Hence, I recommend adding the following snippet to error-handler.js:

require('bluebird').config({
    longStackTraces: true
});

and then rerunning the failing operation.

I tested this on a sequence of operations identical to that in cacache/lib/content/read.js where the EISDIR error is likely to occur and seeded the EISDIR error.

Sorry for the confusion!

PS: a possible idea might be to configure bluebird to maintain long stack traces if npm’s loglevel is set to silly, e.g. if the user runs with -ddd. Due to the associated slowdown it probably can’t be an option that’s on by default.

Update: See also 8203