nodejs/node · error · Error
Tag name must not be a valid SemVer range: ${t}
Error message
Tag name must not be a valid SemVer range: ${t} What it means
When adding a dist-tag, npm rejects tag names that semver.validRange considers a valid range, because such names would collide with version selectors and make `pkg@tag` ambiguous. Only non-range names (next, beta, etc.) are permitted.
Source
Thrown at deps/npm/lib/commands/dist-tag.js:101
async add (spec, tag, opts) {
spec = npa(spec || '')
const version = spec.rawSpec
const defaultTag = tag || this.npm.config.get('tag')
log.verbose('dist-tag add', defaultTag, 'to', spec.name + '@' + version)
// make sure new spec with tag is valid, this will throw if invalid
npa(`${spec.name}@${defaultTag}`)
if (!spec.name || !version || !defaultTag) {
throw this.usageError('must provide a spec with a name and version, and a tag to add')
}
const t = defaultTag.trim()
if (semver.validRange(t)) {
throw new Error('Tag name must not be a valid SemVer range: ' + t)
}
const tags = await this.fetchTags(spec, opts)
if (tags[t] === version) {
log.warn('dist-tag add', t, 'is already set to version', version)
return
}
tags[t] = version
const url =
`/-/package/${spec.escapedName}/dist-tags/${encodeURIComponent(t)}`
const reqOpts = {
...opts,
method: 'PUT',
body: JSON.stringify(version),
headers: {
'content-type': 'application/json',
},
spec,View on GitHub (pinned to 1b2de5e052)
Solutions
- Choose an alphabetic symbolic name (next, beta, release-2, lts)
- Verify your candidate with require('semver').validRange(name) — it must be null
Example fix
# before npm dist-tag add mypkg@1.0.0 '2.x' # after npm dist-tag add mypkg@1.0.0 next
Defensive patterns
Strategy: validation
Validate before calling
const semver = require('semver')
function assertTagName(name) {
if (semver.validRange(name.trim())) {
throw new Error(`Refusing to use '${name}' as a dist-tag: it is a valid semver range`)
}
} Type guard
function isSafeDistTagName(name) {
return !semver.validRange(String(name).trim())
} Prevention
- Use symbolic tag names (next, beta, lts) by convention
- Never derive a tag name from a version string
- Validate with semver.validRange in publish pipelines
When it happens
Trigger: Running `npm dist-tag add pkg@1.0.0 <tag>` where <tag> looks like a version or range: '2.x', '>=2', '1.0.0', '^3'. Edge: some bare versions are also valid ranges and are blocked.
Common situations: Trying to tag a release with the target version number; machine-generated tag names derived from versions.
Related errors
- ${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
- invalid version range: ${spec}
- You must specify a tag using --tag when publishing a prerele
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/1c96f3803de7cdb9.
Report an issue: GitHub.