{"record":{"id":"fa7d4b31b22f9668","repo":"badges/shields","slug":"tag-not-found-fa7d4b","errorCode":null,"errorMessage":"tag not found","messagePattern":"tag not found","errorType":"exception","errorClass":"NotFound","httpStatus":404,"severity":"error","filePath":"services/npm/npm-last-update.service.js","lineNumber":70,"sourceCode":"  }\n\n  static defaultBadgeData = { label: 'last updated' }\n\n  async handle(namedParams, queryParams) {\n    const { scope, packageName, tag, registryUrl } =\n      this.constructor.unpackParams(namedParams, queryParams)\n\n    const packageData = await this.fetch({\n      registryUrl,\n      scope,\n      packageName,\n      schema: fullSchema,\n    })\n\n    const tagVersion = packageData['dist-tags'][tag]\n\n    if (!tagVersion) {\n      throw new NotFound({ prettyMessage: 'tag not found' })\n    }\n\n    return renderDateBadge(packageData.time[tagVersion])\n  }\n}\n\nexport class NpmLastUpdate extends NpmBase {\n  static category = 'activity'\n\n  static route = this.buildRoute('npm/last-update', { withTag: false })\n\n  static openApi = {\n    '/npm/last-update/{packageName}': {\n      get: {\n        summary: 'NPM Last Update',\n        parameters: [\n          pathParam({\n            name: 'packageName',","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/badges/shields/blob/766fd8bc89a90b8534dc573ab72dec30215ab1ec/services/npm/npm-last-update.service.js#L52-L88","documentation":"The npm last-update service fetches full package metadata, reads packageData['dist-tags'][tag] for the requested (or default) tag, and throws NotFound 'tag not found' when the lookup is falsy. This is a plain undefined check, so it fires both when the tag is absent and when the dist-tags object itself is missing. The badge then shows the service's not-found state.","triggerScenarios":"Badge URL with ?tag=x where packageData['dist-tags'] has no 'x' key; default 'latest' lookup on malformed metadata lacking dist-tags; tag names with different casing than published.","commonSituations":"Querying prerelease tags (next/canary) on packages that never created them; tags removed after deprecation; typos such as ?tag=Latst.","solutions":["Check existing tags with `npm dist-tags ls <package>` and use a valid one","Drop the ?tag parameter to fall back to 'latest'","Create the tag if you own the package: `npm dist-tag add <pkg>@<version> <tag>`","Verify spelling and case of the tag in the badge URL"],"exampleFix":"// before\n/npm-last-update/express/badge.svg?tag=edge   // no 'edge' tag\n// after\n/npm-last-update/express/badge.svg            // defaults to 'latest'","handlingStrategy":"validation","validationCode":"const meta = await fetch(`https://registry.npmjs.org/${pkg}`).then(r => r.json())\nif (!meta['dist-tags'] || !(tag || 'latest' in meta['dist-tags'])) {\n  throw new Error(`tag '${tag}' not found; have: ${Object.keys(meta['dist-tags'] || {})}`)\n}","typeGuard":"function tagExists(meta, tag) {\n  const t = tag || 'latest'\n  return Boolean(meta && meta['dist-tags'] && meta['dist-tags'][t])\n}","tryCatchPattern":"try {\n  return await lastUpdateBadge({ pkg, tag })\n} catch (e) {\n  if (e instanceof NotFound && e.message === 'tag not found') {\n    return lastUpdateBadge({ pkg }) // default to latest\n  }\n  throw e\n}","preventionTips":["Verify the tag exists with `npm dist-tags ls <pkg>` before embedding it in a URL","Omit ?tag for the common latest-publish-date case","Check tag spelling and casing — dist-tag keys are case-sensitive","If you removed a release, remember its dist-tag may have been deleted too"],"tags":["npm","not-found","dist-tags"],"backgroundTag":"dist-tag-not-found","analyzedSha":"766fd8bc89a90b8534dc573ab72dec30215ab1ec","analyzedAt":"2026-08-30T01:40:27.499Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}