Tested on
- npm
- 11.9.0 and 12.2.1; re-run on 11.21.1 and 12.2.1 (Linux)
- Node
- 24.14.0
- OS
- Windows 11 Pro
Contents
npm checks versions against semantic versioning: exactly three numbers, MAJOR.MINOR.PATCH, with an optional -beta-style tag. Anything else fails. I tried nine version strings, and the error showed up in two different places with two different messages:
| Where the bad version is | Message | Commands that fail |
|---|---|---|
A dependency’s entry in package-lock.json |
npm error Invalid Version: 7.0 (capital V, the bad version after it) |
npm ci and npm install |
The version field of your own package.json |
npm error Invalid version: patch (small v, then the word you typed) |
only npm version |
Check which one you have before changing anything. The second message names patch or prerelease, not a version, which makes it look like a problem with the command.
Invalid Version: 7.0 (the lockfile)
This one stopped every install. I took a working package-lock.json and changed one dependency’s version field. Both npm ci and npm install failed on npm 11.9.0 and on npm 12.2.1:
Lockfile version for is-number |
npm ci |
npm install |
|---|---|---|
7.0.0 (original) |
worked | worked |
7.0 |
Invalid Version: 7.0 |
Invalid Version: 7.0 |
7.0.0a2 |
Invalid Version: 7.0.0a2 |
Invalid Version: 7.0.0a2 |
"" (empty) |
EUSAGE (lock out of sync) |
worked, and repaired the entry |
npm writes registry versions into the lockfile exactly as published, and those are valid semver, so an entry like 7.0 was edited after npm wrote it: by hand, while resolving a merge conflict, or by another tool. The message gives you the bad string to search for.
Find the entry first, so you know which package it is:
grep -n '"version": "7.0"' package-lock.jsonThen rebuild the lockfile from package.json:
rm -rf node_modules package-lock.json
npm installRebuilding can pull in newer versions within your ranges. If you need the old lockfile exactly, fix only the one version field by hand, using the version from that package’s own package.json in node_modules or the registry.
Invalid version: patch (your package.json)
npm version patch reads your current version and adds one to the last number. When the current version isn’t valid semver, it can’t, and it names the bump you asked for instead:
npm error Invalid version: patch
npm version prerelease failed the same way. Here’s what each version string in package.json did on npm 11.9.0:
"version" in package.json |
npm version patch |
|---|---|
1.0.0 |
v1.0.1 |
1.0.0-beta |
v1.0.0 |
v1.0.0 |
v1.0.1 (the v is tolerated) |
" 1.0.0 " (spaces) |
v1.0.1 |
"" (empty) |
v0.0.1 |
1.0 |
Invalid version: patch |
0.1.0a2 |
Invalid version: patch |
4.2 11 |
Invalid version: patch |
01.0.0 (leading zero) |
Invalid version: patch |
npm install and npm pack worked with every one of them. Only npm version checks your own version this strictly.
Set a valid version once, by giving npm version the number itself:
npm version 1.0.1 --no-git-tag-versionLeave out --no-git-tag-version if you want npm to commit and tag the change as usual.
npm 12.2.1 gave exactly the same Invalid version: patch.
What doesn’t cause it
A local dependency ("dep": "file:./dep") whose own package.json said "version": "1.0" installed fine, and npm ci kept working with it in the lockfile. Only registry packages (node_modules/... entries) were checked strictly.
How I produced each one
Windows 11 Pro, Node 24.14.0, npm 11.9.0 and npm 12.2.1 (through npx npm@12, which warned that it wants Node 24.15 or newer but ran), October 21, 2026. Nine version strings in a project’s own package.json with npm install, npm version patch, npm version prerelease and npm pack, then four edits of one dependency’s lockfile entry with npm ci, npm install and npm ls. Every message above is the real output.
November 3, 2026: both tables were re-run on npm 11.21.1 and 12.2.1 (Node 24, GitHub Actions ubuntu-latest), editing a real package-lock.json for is-number and the version field of a test package.json. Every row matched on both npm versions, including the empty lockfile version that npm ci rejects as out of sync while npm install repairs it. The script and the run are public.
— N.K., end of entry No.084