{"record":{"id":"234d548801b91024","repo":"nodejs/node","slug":"tag-is-not-a-dist-tag-on-spec-name","errorCode":null,"errorMessage":"${tag} is not a dist-tag on ${spec.name}","messagePattern":"(.+?) is not a dist-tag on (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"deps/npm/lib/commands/dist-tag.js","lineNumber":136,"sourceCode":"      },\n      spec,\n    }\n    await otplease(this.npm, reqOpts, o => npmFetch(url, o))\n    output.standard(`+${t}: ${spec.name}@${version}`)\n  }\n\n  async remove (spec, tag, opts) {\n    spec = npa(spec || '')\n    log.verbose('dist-tag del', tag, 'from', spec.name)\n\n    if (!spec.name) {\n      throw this.usageError()\n    }\n\n    const tags = await this.fetchTags(spec, opts)\n    if (!tags[tag]) {\n      log.info('dist-tag del', tag, 'is not a dist-tag on', spec.name)\n      throw new Error(tag + ' is not a dist-tag on ' + spec.name)\n    }\n    const version = tags[tag]\n    delete tags[tag]\n    const url =\n      `/-/package/${spec.escapedName}/dist-tags/${encodeURIComponent(tag)}`\n    const reqOpts = {\n      ...opts,\n      method: 'DELETE',\n      spec,\n    }\n    await otplease(this.npm, reqOpts, o => npmFetch(url, o))\n    output.standard(`-${tag}: ${spec.name}@${version}`)\n  }\n\n  async list (spec, opts) {\n    if (!spec) {\n      if (this.npm.global) {\n        throw this.usageError()","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/npm/lib/commands/dist-tag.js#L118-L154","documentation":"`npm dist-tag rm <pkg> <tag>` fetches current tags and requires the named tag to exist; if tags[tag] is falsy it logs an info line and throws '<tag> is not a dist-tag on <pkg>'. This prevents no-op or misspelled deletions.","triggerScenarios":"Removing a tag that was already deleted, never created, or misspelled; operating on the wrong package name.","commonSituations":"Re-running a release script after a partial failure; concurrent publishes removing the same tag; typos like 'lates' instead of 'latest'.","solutions":["List existing tags first: `npm dist-tag ls <pkg>`","Correct the tag name to match an existing one","Make deletion idempotent in scripts by checking the list before calling rm"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async function tagExists(npm, spec, tag) {\n  const tags = await fetchTags(npm, spec) // same endpoint npm uses\n  return Object.prototype.hasOwnProperty.call(tags, tag)\n}","typeGuard":"function hasDistTag(tags, tag) {\n  return tags && Object.prototype.hasOwnProperty.call(tags, tag)\n}","tryCatchPattern":"try {\n  await npmDistTagRm(pkg, tag)\n} catch (e) {\n  if (/is not a dist-tag/.test(e.message)) { /* already gone; treat as success */ }\n  else throw e\n}","preventionTips":["List tags with `npm dist-tag ls` before removing","Make rm idempotent in release scripts (check existence first)","Watch for typos in tag names"],"tags":["dist-tag","cli","registry","publishing"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}