{"record":{"id":"d94a457a5f0f0c2e","repo":"pnpm/pnpm","slug":"no-matching-version","errorCode":"NO_MATCHING_VERSION","errorMessage":"No matching version found for ${dep} while fetching it from ${opts.registry}","messagePattern":"No matching version found for (.+?) while fetching it from (.+?)","errorType":"exception","errorClass":"NoMatchingVersionError","httpStatus":null,"severity":"error","filePath":"pnpm11/resolving/npm-resolver/src/index.ts","lineNumber":711,"sourceCode":"          projectDir: opts.projectDir,\n          lockfileDir: opts.lockfileDir,\n          hardLinkLocalPackages: opts.injectWorkspacePackages === true || wantedDependency.injected,\n          update: false,\n          saveWorkspaceProtocol: ctx.saveWorkspaceProtocol,\n          calcSpecifier: opts.calcSpecifier,\n          rangeSpecStyle: opts.rangeSpecStyle,\n        })\n      } catch (workspaceErr) {\n        // Neither the registry nor the workspace has a matching version; the\n        // workspace mismatch error carries the available local versions,\n        // which is the actionable detail here.\n        if ((workspaceErr as { code?: string }).code === 'ERR_PNPM_NO_MATCHING_VERSION_INSIDE_WORKSPACE') {\n          throw workspaceErr\n        }\n      }\n    }\n\n    throw new NoMatchingVersionError({ wantedDependency, packageMeta: meta, registry })\n  } else if (opts.trustPolicy === 'no-downgrade') {\n    failIfTrustDowngraded(meta, pickedPackage.version, opts)\n  }\n\n  const latest = latestAllowedByPolicy(meta, opts)\n  const workspacePkgsMatchingName = workspacePackages?.get(pickedPackage.name)\n  if (workspacePkgsMatchingName && opts.projectDir) {\n    const matchedPkg = workspacePkgsMatchingName.get(pickedPackage.version)\n    if (matchedPkg) {\n      return {\n        ...resolveFromLocalPackage(matchedPkg, spec, {\n          wantedDependency,\n          projectDir: opts.projectDir,\n          lockfileDir: opts.lockfileDir,\n          hardLinkLocalPackages: opts.injectWorkspacePackages === true || wantedDependency.injected,\n          saveWorkspaceProtocol: ctx.saveWorkspaceProtocol,\n          calcSpecifier: opts.calcSpecifier,\n          rangeSpecStyle: opts.rangeSpecStyle,","sourceCodeStart":693,"sourceCodeEnd":729,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/resolving/npm-resolver/src/index.ts#L693-L729","documentation":"NoMatchingVersionError is thrown after a packument was successfully fetched but no version satisfies the requested range or dist-tag — and the workspace fallback either found no better answer or rethrew its own workspace-specific error. The error class (exported from @pnpm/resolving.npm-resolver) carries the full `packageMeta`, so handlers can inspect `meta.versions` and `meta['dist-tags']` programmatically instead of parsing the message.","triggerScenarios":"Resolution of `foo@^2.0.0` when the registry packument for `foo` only contains 1.x; a dist-tag that does not exist (`foo@next` when only `latest` is defined); every candidate version filtered out by minimumReleaseAge/publishedBy policies; then the workspace lookup (line ~700-712) also fails and falls through to `throw new NoMatchingVersionError(...)`.","commonSituations":"Bumping a range before the version is published; typos in dist-tags (`next` vs `nightly`); supply-chain maturity policies (minimumReleaseAge) silently filtering the only matching version; stale local metadata caches in CI.","solutions":["See what actually exists: pnpm view <pkg> versions --json and pnpm view <pkg> dist-tags","Fix the range or tag to an existing version (foo@^1.9.0, or the real dist-tag)","If minimumReleaseAge filtered everything out, exclude the package with minimumReleaseAgeExclude: [\"pkg@<exact-version>\"] or shorten the window","If the package is meant to come from the workspace, declare it with the workspace: protocol so resolution prefers local packages"],"exampleFix":"// before (package.json) — only 1.x is published\n\"dep\": \"foo@^2.0.0\"\n\n// after\n\"dep\": \"foo@^1.9.0\"","handlingStrategy":"try-catch","validationCode":"import semver from 'semver'\n// before installing, confirm the range/tag exists in the packument\nexport async function rangeExists (registry: string, name: string, range: string): Promise<boolean> {\n  const meta = await (await fetch(`${registry}/${encodeURIComponent(name).replace('%40', '@')}`)).json()\n  const versions = Object.keys(meta.versions ?? {})\n  if (semver.validRange(range)) return versions.some(v => semver.satisfies(v, range))\n  return Boolean(meta['dist-tags']?.[range])\n}","typeGuard":"import { NoMatchingVersionError } from '@pnpm/resolving.npm-resolver'\nfunction isNoMatchingVersionError (err: unknown): err is NoMatchingVersionError {\n  return err instanceof NoMatchingVersionError ||\n    (typeof err === 'object' && err !== null && (err as { code?: string }).code === 'ERR_PNPM_NO_MATCHING_VERSION')\n}","tryCatchPattern":"try {\n  const result = await npmResolver.resolve(spec, opts)\n} catch (err) {\n  if (isNoMatchingVersionError(err)) {\n    const versions = Object.keys(err.packageMeta.versions ?? {}).sort(semver.rcompare)\n    const tags = err.packageMeta['dist-tags'] ?? {}\n    // report or fall back: suggest the closest satisfying version or the real dist-tag\n    throw new Error(`No match for ${spec.pref}; published: ${versions.slice(0, 5).join(', ')}; tags: ${JSON.stringify(tags)}`)\n  }\n  throw err\n}","preventionTips":["Check `pnpm view <pkg> versions` and `dist-tags` before pinning or bumping ranges","When enabling minimumReleaseAge/publishedBy policies, pre-plan excludes for packages that publish fresh versions you need","In automation, catch NoMatchingVersionError and use err.packageMeta to pick a fallback instead of parsing the message"],"tags":["npm-registry","version-resolution","semver","resolver"],"backgroundTag":"no-matching-version","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}