Deploy Error Decoder

'npm ci' lock-file errors — get a clean, reproducible install

Quick answer: npm ci is the strict, reproducible install for CI - it requires a package-lock.json that exactly matches package.json. It fails if the lock file is missing, gitignored, or out of sync. Fix: run npm install to regenerate the lock, commit it, make sure it is not ignored, and pin the same npm/Node version in CI as locally.

Not your exact error? Paste it into the Deploy Error Decoder →

What the error looks like

Two common forms, both during npm ci in CI or a deploy:

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.

# or, when there is no lock file at all:
npm ci can only install with an existing package-lock.json or npm-shrinkwrap.json

Both mean the same thing: npm ci wants a lock file that exactly matches package.json, and it did not find one in sync.

Why it happens

No lock file committed

package-lock.json was never committed, or it is in .gitignore, so CI never sees it.

package.json edited, lock not updated

A dependency was added or bumped by hand without running npm install, so the lock is stale.

Different npm version

CI runs a different npm major than local, producing a different lock format or resolution.

Bad merge of the lock file

A merge left package-lock.json inconsistent with package.json.

Diagnose it in three steps

1

Is the lock file committed?

git ls-files package-lock.json
# prints the path if tracked; empty output means it is not committed.
2

Is it gitignored?

git check-ignore package-lock.json
# prints the path if ignored - remove it from .gitignore.
3

Is it in sync?

npm install
git diff --stat package-lock.json
# if the lock changes, it was out of sync - commit the update.
The real fix

Commit a matching lock file, pin the version

Regenerate the lock so it matches package.json, commit it, and make sure it is tracked - not ignored. Then pin the same npm/Node version in CI as you run locally so the lock stays consistent across environments.

# sync and commit the lock file
npm install
git add package-lock.json
git commit -m "sync package-lock with package.json"

# make sure it is not ignored (should print nothing)
git check-ignore package-lock.json

# pin Node/npm in CI so the lock stays in sync
echo "20" > .nvmrc   # and use setup-node with node-version-file

From then on, run npm ci in CI and deploys for a clean, exact, reproducible install, and use npm install locally whenever you change dependencies - committing the updated lock each time.

How Infraveil handles this

Reproducible installs, pinned toolchain

Lock-file drift is a reproducibility problem - the build depends on which machine and npm version ran it. On your own servers, Infraveil runs your deploy with a pinned, consistent Node/npm, so npm ci stays deterministic, a failed install is caught before it ships, and the fix is approval-gated and recorded.

One pinned Node/npm version across every install, on infra you control
Failed installs caught and surfaced before they reach production
Every deploy approval-gated and recorded

Frequently asked questions

What is the difference between npm ci and npm install?

npm ci does a clean, exact install from the lock file - it removes node_modules first, is faster, and fails if the lock is out of sync. npm install resolves dependencies and updates the lock. Use npm install locally, npm ci in CI and deploys.

Why does it say my lock file is out of sync?

package.json changed - a dependency added, removed, or bumped - without running npm install, so package-lock.json no longer matches. Run npm install and commit the updated lock.

Should I commit package-lock.json?

Yes, always, for an app - it pins the exact dependency tree for reproducible installs. Never gitignore it; a missing lock is the most common cause of npm ci failing in CI.

Does the npm or Node version matter?

Yes - different npm majors can produce different lock formats, which can read as out-of-sync in CI even when it works locally. Pin the same npm/Node version everywhere.