The error, verbatim
Jump to the fix ↓npm error code EUSAGE
npm error `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
npm error Missing: is-number@7.0.0 from lock file
Tested on
- npm
- 11.9.0 / 12.2.0; re-tested on 11.21.1 / 12.2.1
- Node
- 24.14.0
- OS
- Windows 11 Pro
✓ Last re-run on GitHub Actions · see the run · all repros
Contents
npm ci installs exactly what package-lock.json says, and refuses to start if that file doesn’t match package.json. It never updates the lockfile itself, which is the point: in CI you get what was committed or nothing. So the error isn’t about your packages. It’s about the two files disagreeing, and the line after the long message says where:
| The line under the message | Cause |
|---|---|
Missing: is-number@7.0.0 from lock file |
A dependency was added but the lockfile wasn’t updated |
Invalid: lock file's ms@2.1.2 does not satisfy ms@2.1.3 |
A version range was changed by hand |
Missing: react@18.3.1 from lock file, a package you never added |
The lockfile was made with --legacy-peer-deps |
Invalid: …, and you just added overrides |
An override the lockfile doesn’t reflect |
Missing: …, in a monorepo |
A workspace’s own package.json changed |
can only install with an existing package-lock.json |
There is no lockfile at all |
I reproduced each one on Windows 11 with npm 11.9.0 and 12.2.0. Both print the same lines, except that npm 12 no longer mentions npm-shrinkwrap.json.
1. Missing: a dependency the lockfile doesn’t have
The usual one. A dependency went into package.json, by hand, by a merge, or by npm install on a machine whose updated lockfile was never committed. Locally everything works, because npm install quietly fixes the lockfile. CI runs npm ci, which won’t:
npm error code EUSAGE
npm error `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
npm error Missing: is-number@7.0.0 from lock file
Rewrite the lockfile from package.json, then commit it:
npm install --package-lock-onlyThe fix only reaches CI once the new package-lock.json is committed and pushed. Check git status after running it: if the lockfile isn’t listed as changed, you’re looking at a different cause.
2. Invalid: a range was edited in package.json
Changing a version in package.json without reinstalling leaves the lockfile pointing at a version the new range no longer allows. I had ms pinned to 2.1.2, then changed it to ^2.1.3:
npm error code EUSAGE
npm error Invalid: lock file's ms@2.1.2 does not satisfy ms@2.1.3
Same fix: let npm resolve the new range and write it down.
npm install --package-lock-only3. Missing: a peer dependency (legacy-peer-deps)
This one names a package you never added. I installed react-dom@18.3.1 with --legacy-peer-deps, which tells npm to skip peer dependencies, so react never went into the lockfile. A plain npm ci does install peers, wants react, and can’t find it:
npm error code EUSAGE
npm error Missing: react@18.3.1 from lock file
It happens whenever someone fixes an ERESOLVE on their own machine with --legacy-peer-deps, and CI installs without it.
Make the setting part of the project, so every install uses it. Add an .npmrc next to package.json and commit it:
legacy-peer-deps=truePassing npm ci --legacy-peer-deps in the CI step also works, but the next teammate who runs npm install without the flag rewrites the lockfile the other way.
4. Invalid: after adding overrides
overrides change which version npm should use, so they have to be in the lockfile too. I added "overrides": { "ms": "2.1.3" } to a project whose lockfile had ms 2.1.2 (via debug):
npm error code EUSAGE
npm error Invalid: lock file's ms@2.1.2 does not satisfy ms@2.1.3
Run an install once so the override is applied and recorded, then commit the lockfile:
npm install5. A workspace dependency in a monorepo
Workspaces share the root package-lock.json. Adding a dependency to packages/app/package.json by hand doesn’t touch it, and npm ci at the root fails with the same Missing: line:
npm error code EUSAGE
npm error Missing: ms@2.1.3 from lock file
Run the install from the repository root, not inside the workspace, so the root lockfile is the one that gets updated:
npm install6. No lockfile
Same error code, different message. The lockfile isn’t in the repository, often because .gitignore lists it:
npm error code EUSAGE
npm error The `npm ci` command can only install with an existing package-lock.json or
npm error npm-shrinkwrap.json with lockfileVersion >= 1. Run an install with npm@5 or
npm error later to generate a package-lock.json file, then try again.
Create it, remove it from .gitignore if it’s there, and commit it:
npm installWhat didn’t work
How this was tested
npm 11.9.0 (bundled with Node 24.14.0) and npm 12.2.0, on Windows 11 Pro, on October 12, 2026. Each cause ran in a fresh project: I created an in-sync lockfile with npm install, changed one thing, and ran npm ci. Packages came from registry.npmjs.org (ms, is-number, debug, react, react-dom). Every message above is the real output.
November 2, 2026: all six causes, both fixes that didn’t work, and every fix were re-run on npm 11.21.1 and 12.2.1 (Node 24.22.1, GitHub Actions ubuntu-latest). Every message and result matched on both. The script and output are public.
— N.K., end of entry No.062