npm "Cannot read properties of null" Engine Error in CI - Fix Corrupted State
A "Cannot read properties of null" crash from the npm engine is an internal error, usually triggered by a malformed lockfile, a corrupted cache, or an npm version that mishandles your tree.
What this error means
npm install or npm ci throws a TypeError that it cannot read a property (often reading or matches) of null, with a stack trace inside npm internals rather than your code.
npm ERR! Cannot read properties of null (reading 'matches')
npm ERR! A complete log of this run can be found in:
npm ERR! /home/runner/.npm/_logs/2026-06-26T00_00_00_000Z-debug.logDiagnose it: reproduce the CI install locally
Install failures are usually environment drift rather than a broken lockfile: a different package-manager major, a different Node version, or a cache that is being restored from a run with different inputs. Reproduce the CI conditions before changing the lockfile, because regenerating it hides the real cause.
# match the runner exactly, then install from a clean slate
node --version && npm --version
rm -rf node_modules
npm ci --foreground-scripts
# if that succeeds locally but fails in CI, the difference is the cache
# or the package-manager version, not your lockfileCommon causes
A corrupted lockfile or cache
A malformed package-lock.json or a poisoned ~/.npm cache feeds null into npm internals, crashing the resolver.
An npm version mismatch with the lockfile format
An old npm reading a newer lockfileVersion (or the reverse) can hit code paths that assume data that is not present.
How to fix it
Clear state and reinstall clean
- Remove node_modules, package-lock.json, and clean the cache.
- Reinstall so npm rebuilds a consistent tree.
rm -rf node_modules package-lock.json
npm cache clean --force
npm installAlign the npm version
- Pin a known-good npm version in CI.
- Regenerate the lockfile with that version and commit it.
npm install -g npm@10Verify the fix survives a cold cache
A green run immediately after a fix often proves nothing, because it restored a cache written before the change. Force a cold install once to confirm the fix is real.
# temporarily bust the cache key to prove the fix on a cold runner
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json
# then bump this suffix once, run, and remove it
# key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}-v2How to prevent it
- Pin one npm version across local and CI, commit a lockfile generated by it, and cache ~/.npm keyed on the lockfile so corruption does not persist across runs.