nodejs/node · error · Error
invalid version range: ${spec}
Error message
invalid version range: ${spec} What it means
`npm deprecate <pkg@range> <msg>` parses the spec and validates the range portion with semver.validRange. A dist-tag (e.g. 'latest') or malformed range fails this check and is rejected before any registry call.
Source
Thrown at deps/npm/lib/commands/deprecate.js:47
return Object.keys(packages)
.filter((name) =>
packages[name] === 'write' &&
(opts.conf.argv.remain.length === 0 ||
name.startsWith(opts.conf.argv.remain[0])))
}
async exec ([pkg, msg]) {
// msg == null because '' is a valid value, it indicates undeprecate
if (!pkg || msg == null) {
throw this.usageError()
}
// fetch the data and make sure it exists.
const p = npa(pkg)
const spec = p.rawSpec === '*' ? '*' : p.fetchSpec
if (semver.validRange(spec, true) === null) {
throw new Error(`invalid version range: ${spec}`)
}
const uri = '/' + p.escapedName
const packument = await npmFetch.json(uri, {
...this.npm.flatOptions,
spec: p,
query: { write: true },
})
const versions = Object.keys(packument.versions)
.filter(v => semver.satisfies(v, spec, { includePrerelease: true }))
const dryRun = this.npm.config.get('dry-run')
if (versions.length) {
for (const v of versions) {
packument.versions[v].deprecated = msg
if (msg) {View on GitHub (pinned to 1b2de5e052)
Solutions
- Provide a valid semver range, e.g. `npm deprecate pkg@'<2.0.0' 'msg'`
- Use '*' to deprecate every version: `npm deprecate pkg@'*' 'msg'`
- Pre-validate the range with require('semver').validRange(spec) in your script
Example fix
# before npm deprecate mypkg@latest "broken in 1.x" # after npm deprecate mypkg@'1.x' "broken in 1.x"
Defensive patterns
Strategy: validation
Validate before calling
const semver = require('semver')
function resolveDeprecateRange(spec) {
const p = require('npm-package-arg')(spec)
const range = p.rawSpec === '*' ? '*' : p.fetchSpec
if (semver.validRange(range, true) === null) {
throw new Error(`Refusing to deprecate: '${range}' is not a valid semver range`)
}
return range
} Type guard
function isValidDeprecateRange(spec) {
const p = require('npm-package-arg')(spec)
const range = p.rawSpec === '*' ? '*' : p.fetchSpec
return semver.validRange(range, true) !== null
} Prevention
- Pass an explicit semver range rather than a dist-tag
- Pre-validate ranges with semver.validRange in release scripts
- Use '*' only when you genuinely mean all versions
When it happens
Trigger: Passing a dist-tag where a semver range is required (npm deprecate pkg@latest 'msg'), or a syntactically broken range like pkg@'>=1.<2'. Note '*' is allowed because the code special-cases rawSpec === '*' to '*'.
Common situations: Assuming deprecate accepts the same spec forms as install; copy-pasting a version expression with broken operators.
Related errors
- Tag name must not be a valid SemVer range: ${t}
- ${tag} is not a dist-tag on ${spec.name}
- No dist-tags found for ${spec.name}
- Tag name must not be a valid SemVer range: ${defaultTag.trim
- Cannot use --no-workspaces and --workspace at the same time
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/d2253bbdcf23e762.
Report an issue: GitHub.