pnpm/pnpm · error · PnpmError
DIST_TAG_ADD_INVALID_VERSION
DIST_TAG_ADD_INVALID_VERSION
Error message
Version must be an exact semver version, got "${version}" What it means
The version part of the dist-tag add spec failed semver.valid(): dist-tags must reference one concrete version, so ranges (^1.0.0, ~1.2, 1.x) and partials (1.2) are rejected. The offending value is embedded in the message. Thrown before any registry access.
Source
Thrown at pnpm11/registry-access/commands/src/distTag.ts:145
return lines.join('\n')
}
async function distTagAdd (
opts: DistTagOptions,
params: string[]
): Promise<string> {
if (params.length === 0) {
throw new PnpmError('DIST_TAG_ADD_SPEC_REQUIRED', 'Package name and version are required (e.g., pnpm dist-tag add pkg@1.0.0 latest)')
}
const { name: packageName, versionRange: version } = parsePackageSpec(params[0])
if (!version) {
throw new PnpmError('DIST_TAG_ADD_VERSION_REQUIRED', 'Version is required (e.g., pnpm dist-tag add pkg@1.0.0 latest)')
}
if (!semver.valid(version)) {
throw new PnpmError('DIST_TAG_ADD_INVALID_VERSION', `Version must be an exact semver version, got "${version}"`)
}
const tag = params[1] ?? 'latest'
const registryUrl = pickRegistryForPackage(opts.registriesByScope ?? { default: 'https://registry.npmjs.org/' }, packageName)
const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl, packageName)
const fetchFromRegistry = createFetchFromRegistry(opts)
const cliOtp = opts.cliOptions?.otp
const authType = cliOtp ? 'legacy' : 'web'
await withOtpHandling({
context: createOtpContext(opts),
fetchOptions: WEB_AUTH_FETCH_OPTIONS,
operation: (otp) => setDistTag({
packageName,
version,
distTag: tag,
registryUrl,View on GitHub (pinned to 6261b7f388)
Solutions
- Pin an exact version: pnpm dist-tag add mypkg@1.4.0 next
- Resolve the range first: pnpm view mypkg@^1.0.0 version, then use the printed version
Example fix
# before - a range is not an exact version pnpm dist-tag add mypkg@^1.0.0 next # after pnpm view mypkg@^1.0.0 version # prints 1.4.0 pnpm dist-tag add mypkg@1.4.0 next
Defensive patterns
Strategy: validation
Validate before calling
import semver from 'semver'
const version = splitSpec(params[0] ?? '').version
if (!(version != null && semver.valid(version) != null)) {
throw new Error('dist-tag add needs an exact version like 1.4.0, got: ' + version)
} Type guard
import semver from 'semver' const isExactVersion = (v: string | undefined): v is string => v != null && semver.valid(v) != null
Prevention
- Resolve ranges to concrete versions before tagging: pnpm view <pkg>@<range> version
- Validate with semver.valid() when building specs programmatically
When it happens
Trigger: pnpm dist-tag add mypkg@^1.0.0 next; pnpm dist-tag add mypkg@1.2 latest; copy-pasting a semver range from package.json dependencies as the version.
Common situations: Pasting a dependency range where a version belongs; scripting with a range or alias instead of a resolved concrete version.
Related errors
- NO_MATCHING_VERSIONS
- DIST_TAG_ADD_VERSION_REQUIRED
- INVALID_${key.replace(/([A-Z])/g, '_$1').toUpperCase()}
- INVALID_VERSION_UNION
- INVALID_PACKAGE_NAME
AI-assisted analysis of pnpm/pnpm@6261b7f388 (2026-08-17).
Data as JSON: /api/errors/e14bc67c1e12261e.
Report an issue: GitHub.