TL;DR: node_modules no longer matches what package.json and package-lock.json describe, usually after a partial upgrade, a hand edit, or switching branches with a stale install. Delete node_modules and reinstall so npm rebuilds the tree from the lockfile. In CI, use npm ci, which does this deterministically by design.

```text
npm ERR! code ELSPROBLEMS
npm ERR! invalid: [package]@[version] [path]
```

1. See the extent of the drift: `npm ls 2>&1 | head -30`.
   Expected: lines marked "invalid:" show which installed packages disagree with the lockfile.
2. For local development, wipe and reinstall: `rm -rf node_modules && npm install`.
   Expected: npm rebuilds the tree; a follow-up `npm ls` shows no "invalid:" lines.
3. For CI, use `npm ci` instead of `npm install`.
   Expected: npm deletes node_modules itself and installs exactly what the lockfile describes; ELSPROBLEMS is gone.
4. Verify: `npm ls`.
   Expected: the tree prints with no "invalid:" or "extraneous:" complaints about the upgraded packages.
5. If the upgrade legitimately changed dependencies, commit the updated package-lock.json.
   Expected: teammates and CI resolve the same tree you just verified.

## Use this when
- npm fails with the ELSPROBLEMS code and "invalid:" entries.
- The drift followed a partial upgrade, an interrupted install, or a branch switch.
- node_modules was copied between machines or branches instead of reinstalled.

## Not for this skill when
- The error is ERESOLVE; that is a version conflict to resolve, not a drifted tree.
- The project uses pnpm or yarn; their lockfiles and install commands differ.
- `npm ls` shows only "extraneous" warnings with no failure; those are informational.

## Variant phrasings
- "npm ERR ELSPROBLEMS invalid node_modules"
- "npm tree out of sync after upgrade"
- "npm ERR code ELSPROBLEMS invalid after partial install"
- "node_modules out of sync with package-lock.json"

## Why it happens
npm treats package-lock.json as the source of truth for the intended tree. Hand edits to package.json, interrupted installs, or switching branches without reinstalling leave node_modules describing a different tree than the lockfile. npm detects the divergence and refuses to operate on a tree it cannot reconcile, reporting each mismatched package as invalid.

## Edge cases
- npm ci always starts from a clean slate, which is why it is the right CI command; npm install tries to preserve the existing tree.
- Agents that edit package.json must always follow with an install in the same run; the edit alone guarantees this error.
- Never commit node_modules to work around it; the drift returns on the next machine.
- If invalid entries persist after a clean install, the lockfile itself is corrupt; regenerate it and review the diff.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_k-d4wThIARCX_teq1J6M3w
