npm / npm/cli

[BUG] package.json has "lockfileVersion": 2 but is missing "hasInstallScript": true

Open
#2,606 23 comments 30 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Priority 1 Release 7.x
Dominant language
JavaScript
Stars
10.1k
Forks
4.7k
Avg merge
2d 2h
Merged PRs (30d)
19

Description

My apologies if this is a duplicate. The closest I could find is https://github.com/npm/cli/issues/1905, but the fix didn't solve the problem in this issue.

Current Behavior:

The user-facing issue is that you can get into a state where npm ci fails to run the postinstall scripts of all of your dependencies, resulting in broken packages. This appears to be because of a missing "hasInstallScript": true in my package-lock.json file.

I'm not familiar with npm's internals but I did some debugging and I believe one way to get into this state is by running npm install on a package-lock.json file with "lockfileVersion": 1 with npm v7. This upgrades the package-lock.json file to "lockfileVersion": 2 but doesn't add "hasInstallScript": true where it would usually be added. That then causes npm ci to fail to reinstall the package correctly. There may also be other ways of getting into this state.

Expected Behavior:

I expect running npm ci on a package-lock.json file that has been upgraded from "lockfileVersion": 1 to "lockfileVersion": 2 to behave the same as npm ci on a package-lock.json file that was always "lockfileVersion": 2.

Steps To Reproduce:

Steps to demonstrate the current unexpected behavior:

$ npm i -g npm@6.14.11
$ echo '{}' > package.json
$ npm i esbuild@0.8.39
$ cat package-lock.json | grep -E 'lockfileVersion|hasInstallScript'
  "lockfileVersion": 1,
$ npm i -g npm@7.5.2
$ npm i esbuild@0.8.39
$ cat package-lock.json | grep -E 'lockfileVersion|hasInstallScript'
  "lockfileVersion": 2,
$ npm ci
$ ./node_modules/.bin/esbuild --version
Error: esbuild: Failed to install correctly

Steps to demonstrate the desired behavior:

$ npm i -g npm@7.5.2
$ echo '{}' > package.json
$ npm i esbuild@0.8.39
$ cat package-lock.json | grep -E 'lockfileVersion|hasInstallScript'
  "lockfileVersion": 2,
      "hasInstallScript": true,
$ npm ci
$ ./node_modules/.bin/esbuild --version
0.8.39
Environment:
  • OS: macOS 10.15.7
  • Node: 15.2.0
  • npm: 7.5.2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the upgrade path from npm 6 with a lockfileVersion 1 package-lock.json to npm 7, then run npm ci with esbuild as shown. Trace the lockfile migration and install-script handling; done means the upgraded lockfile records hasInstallScript for packages needing it and npm ci runs their postinstall scripts correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
cli, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.