4

I have node v15.14.0 and npm 7.8.0 on Arch Linux x86_64 (installed from that distro's repos).

Starting a project in an empty directory with npm init and then trying to install something with npm i <blah> always fails in the same fashion. An example, run in $HOME/tmp:

$ npm i btoa
npm ERR! subset is not a function

npm ERR! A complete log of this run can be found in:
npm ERR!     $HOME/.npm/_logs/2021-04-08T00_32_19_504Z-debug.log

That log file reads as follows:

0 verbose cli [ '/usr/bin/node', '/usr/bin/npm', 'i', 'btoa' ]
1 info using npm@7.8.0
2 info using node@v15.14.0
3 timing npm:load:whichnode Completed in 0ms
4 timing config:load:defaults Completed in 1ms
5 timing config:load:file:/usr/lib/node_modules/npm/npmrc Completed in 0ms
6 timing config:load:builtin Completed in 0ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 0ms
9 timing config:load:file:$HOME/tmp/.npmrc Completed in 0ms
10 timing config:load:project Completed in 1ms
11 timing config:load:file:$HOME/.npmrc Completed in 0ms
12 timing config:load:user Completed in 0ms
13 timing config:load:file:/usr/etc/npmrc Completed in 0ms
14 timing config:load:global Completed in 0ms
15 timing config:load:validate Completed in 0ms
16 timing config:load:setEnvs Completed in 1ms
17 timing config:load Completed in 5ms
18 timing npm:load:configload Completed in 5ms
19 timing npm:load:setTitle Completed in 0ms
20 timing npm:load:setupLog Completed in 1ms
21 timing npm:load:cleanupLog Completed in 1ms
22 timing npm:load:configScope Completed in 1ms
23 timing npm:load:projectScope Completed in 0ms
24 timing npm:load Completed in 9ms
25 timing config:load:flatten Completed in 2ms
26 timing arborist:ctor Completed in 0ms
27 timing arborist:ctor Completed in 0ms
28 timing idealTree:init Completed in 13ms
29 timing idealTree:userRequests Completed in 3ms
30 silly idealTree buildDeps
31 silly fetch manifest btoa@*
32 http fetch GET 304 https://registry.npmjs.org/btoa 193ms (from cache)
33 silly placeDep ROOT btoa@1.2.1 KEEP for: tmp@1.0.0 want: *
34 timing idealTree:#root Completed in 198ms
35 timing idealTree:buildDeps Completed in 199ms
36 timing idealTree:fixDepFlags Completed in 0ms
37 timing idealTree Completed in 217ms
38 timing reify:loadTrees Completed in 217ms
39 timing reify:diffTrees Completed in 0ms
40 silly reify moves {}
41 timing reify:retireShallow Completed in 0ms
42 timing reify:createSparse Completed in 0ms
43 timing reify:loadBundles Completed in 0ms
44 timing reify:unpack Completed in 0ms
45 timing reify:unretire Completed in 0ms
46 timing build:queue Completed in 0ms
47 timing build:deps Completed in 1ms
48 timing build Completed in 1ms
49 timing reify:build Completed in 1ms
50 timing reify:trash Completed in 0ms
51 timing command:install Completed in 230ms
52 verbose stack TypeError: subset is not a function
52 verbose stack     at Arborist.[saveIdealTree] (/usr/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:956:37)
52 verbose stack     at /usr/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:138:39
52 verbose stack     at async Arborist.reify (/usr/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:134:5)
52 verbose stack     at async Install.install (/usr/lib/node_modules/npm/lib/install.js:137:5)
53 verbose cwd $HOME/tmp
54 verbose Linux 5.10.25-1-lts
55 verbose argv "/usr/bin/node" "/usr/bin/npm" "i" "btoa"
56 verbose node v15.14.0
57 verbose npm  v7.8.0
58 error subset is not a function
59 verbose exit 1

So you can see that

  • my "global" modules live in /usr/lib/node_modules (where I can install just fine with sudo npm install -g);
  • the subset function seems to pop up when the install command calls
/usr/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js

I've checked that that file defines

const {subset} = require('semver')

How do I fix this?

Edit:

This is to address a comment below: this subset issue occurs regardless of what I try to install. btoa was nothing but an example.

grobber
  • 1,083
  • 1
  • 9
  • 20
  • Why would you need `btoa` to begin with? Node can already natively convert any data to base64 using Buffer's `toString('base64')`, and convert from base64 using `Buffer.from(data, 'base64')`? – Mike 'Pomax' Kamermans Apr 08 '21 at 01:22
  • It was only an example. The issue replicates with *any* `npm` package whatsoever. – grobber Apr 08 '21 at 01:47
  • Do `npm ls` and `npm ls -g` return without an error? – Trott Apr 08 '21 at 03:28
  • also note that `npm install -g` should never need `sudo` (because that would be an _insane_ security risk. NPM installations can and have been known to, run arbitrary code that can do everything from installing backdoors to running `rm -rf /`). If `npm i -g` doesn't work without it, something went very wrong, and it's probably time to reinstall node... – Mike 'Pomax' Kamermans Apr 08 '21 at 03:59
  • `npm ls -g` always works fine; `npm ls` errors with `extraneous modules` unless I remove `$HOME/node_modules`; if I do, it's fine. – grobber Apr 08 '21 at 04:23

2 Answers2

4

For those who miss papanito's comment

sudo npm i -g npm

Worked for me on Arch.

Adam Lynch
  • 331
  • 2
  • 6
3

I was able to replicate your problem by changing /usr/lib/node_modules/npm/node_modules/semver/ranges/subset.js to be an empty file. Sounds like something went wrong during your installation of npm and at least one dependency (semver) didn't fully install. Or maybe somehow something happened later that overwrote the file to be an empty file.

Your best bet is to reinstall node and npm. But there are narrower things you can try. You say npm install -g is working. I find that surprising, but because that's the case, you can try npm install -g npm to reinstall npm itself. That should fix things. If that doesn't work, you can try npm install --force -g npm.

But again: Your best bet is to reinstall node and npm.

Trott
  • 66,479
  • 23
  • 173
  • 212
  • This fails on multiple levels: `npm install -g` (with or without `--force`) *always* gives me permission errors for renaming files under `/usr/lib/node_modules`, hence my need for sudo; reinstalling `npm` through the distro's package manager did nothing; and `/usr/lib/node_modules/npm/node_modules/semver/ranges/subset.js` looks fine.. – grobber Apr 08 '21 at 04:24
  • 1
    I eventually gave up on my package manager's `node` and `npm`: too much of a headache. I went and installed the [canonical](https://nodejs.org/en/download/) version, and all is well (I can `npm install`, and also `npm install -g` without `sudo`). I will just accept this answer; thank you! – grobber Apr 08 '21 at 05:23
  • 4
    what helped me was `sudo npm install -g npm`. I tried to uninstall/re-install npm via pacman but that did not help. – papanito Apr 09 '21 at 08:31