Skip to content
Latchkey

npm ci "can only install with an existing package-lock.json in sync"

npm ci installs strictly from the lockfile and refuses to run if package.json and package-lock.json disagree. Unlike npm install, it never edits the lockfile to reconcile them.

What this error means

npm ci aborts immediately - before fetching anything - complaining that package.json and package-lock.json are out of sync, and usually lists which dependencies are missing from or extra in the lock. Running it again does not help; the inputs are genuinely mismatched.

npm output
npm error code EUSAGE
npm error `npm ci` can only install packages when your package.json and
npm error package-lock.json or npm-shrinkwrap.json are in sync. Please update
npm error your lock file with `npm install` before continuing.
npm error Missing: left-pad@1.3.0 from lock file

Common causes

package.json was edited without regenerating the lockfile

Someone bumped a version or added a dependency in package.json but did not run npm install to update package-lock.json, so the two files describe different trees.

The lockfile was not committed

A dependency change landed without committing the updated package-lock.json, so CI checks out a stale lock that no longer matches package.json.

A merge left the lockfile half-updated

Resolving a merge conflict in package.json but taking one side of package-lock.json can produce a lock that satisfies neither branch.

How to fix it

Regenerate and commit the lockfile

Run a normal install locally to bring the lockfile back in sync, then commit it.

Terminal
npm install
git add package-lock.json
git commit -m "chore: sync package-lock.json"

Confirm CI is using npm ci deliberately

  1. Keep npm ci in CI - it is the correct strict, reproducible install.
  2. Do not switch CI to npm install to "fix" this; that hides lockfile drift instead of resolving it.
  3. Add a check (e.g. npm install --package-lock-only + git diff --exit-code package-lock.json) to catch drift in PRs.

How to prevent it

  • Always commit package-lock.json alongside any package.json change.
  • Fail PRs that change package.json without an in-sync lockfile.
  • Resolve lockfile merge conflicts by regenerating, not hand-merging.

Frequently asked questions

Why not just run npm install in CI instead?
npm install will silently rewrite the lockfile to make it consistent, which defeats the point of reproducible CI builds. npm ci deliberately fails so that drift is fixed in the repo, not papered over on each run.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →