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 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 fileCommon 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.
npm install
git add package-lock.json
git commit -m "chore: sync package-lock.json"Confirm CI is using npm ci deliberately
- Keep
npm ciin CI - it is the correct strict, reproducible install. - Do not switch CI to
npm installto "fix" this; that hides lockfile drift instead of resolving it. - 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.