{"record":{"id":"e14bc67c1e12261e","repo":"pnpm/pnpm","slug":"dist-tag-add-invalid-version","errorCode":"DIST_TAG_ADD_INVALID_VERSION","errorMessage":"Version must be an exact semver version, got \"${version}\"","messagePattern":"Version must be an exact semver version, got \"(.+?)\"","errorType":"exception","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/registry-access/commands/src/distTag.ts","lineNumber":145,"sourceCode":"  return lines.join('\\n')\n}\n\nasync function distTagAdd (\n  opts: DistTagOptions,\n  params: string[]\n): Promise<string> {\n  if (params.length === 0) {\n    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)')\n  }\n\n  const { name: packageName, versionRange: version } = parsePackageSpec(params[0])\n\n  if (!version) {\n    throw new PnpmError('DIST_TAG_ADD_VERSION_REQUIRED', 'Version is required (e.g., pnpm dist-tag add pkg@1.0.0 latest)')\n  }\n\n  if (!semver.valid(version)) {\n    throw new PnpmError('DIST_TAG_ADD_INVALID_VERSION', `Version must be an exact semver version, got \"${version}\"`)\n  }\n\n  const tag = params[1] ?? 'latest'\n\n  const registryUrl = pickRegistryForPackage(opts.registriesByScope ?? { default: 'https://registry.npmjs.org/' }, packageName)\n  const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl, packageName)\n  const fetchFromRegistry = createFetchFromRegistry(opts)\n  const cliOtp = opts.cliOptions?.otp\n  const authType = cliOtp ? 'legacy' : 'web'\n\n  await withOtpHandling({\n    context: createOtpContext(opts),\n    fetchOptions: WEB_AUTH_FETCH_OPTIONS,\n    operation: (otp) => setDistTag({\n      packageName,\n      version,\n      distTag: tag,\n      registryUrl,","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/registry-access/commands/src/distTag.ts#L127-L163","documentation":"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.","triggerScenarios":"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.","commonSituations":"Pasting a dependency range where a version belongs; scripting with a range or alias instead of a resolved concrete version.","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"],"exampleFix":"# before - a range is not an exact version\npnpm dist-tag add mypkg@^1.0.0 next\n\n# after\npnpm view mypkg@^1.0.0 version   # prints 1.4.0\npnpm dist-tag add mypkg@1.4.0 next","handlingStrategy":"validation","validationCode":"import semver from 'semver'\n\nconst version = splitSpec(params[0] ?? '').version\nif (!(version != null && semver.valid(version) != null)) {\n  throw new Error('dist-tag add needs an exact version like 1.4.0, got: ' + version)\n}","typeGuard":"import semver from 'semver'\n\nconst isExactVersion = (v: string | undefined): v is string =>\n  v != null && semver.valid(v) != null","tryCatchPattern":null,"preventionTips":["Resolve ranges to concrete versions before tagging: pnpm view <pkg>@<range> version","Validate with semver.valid() when building specs programmatically"],"tags":["cli","dist-tag","semver","validation"],"backgroundTag":"invalid-semver-version","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}