{"record":{"id":"9d31fcbd50114fb5","repo":"pnpm/pnpm","slug":"registry-error-9d31fc","errorCode":"REGISTRY_ERROR","errorMessage":"Failed to fetch package info: ${getResponse.status} ${getResponse.statusText}","messagePattern":"Failed to fetch package info: (.+?) (.+?)","errorType":"exception","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/registry-access/commands/src/deprecation/common.ts","lineNumber":57,"sourceCode":"  const registryUrl = pickRegistryForPackage(opts.registriesByScope ?? { default: 'https://registry.npmjs.org/' }, packageName)\n\n  const getAuthHeader = createGetAuthHeaderByURI(opts.configByUri ?? {})\n\n  const authHeader = getAuthHeader(registryUrl, { pkgName: packageName })\n\n  const packageUrl = new URL(npa(packageName).escapedName, registryUrl).href\n\n  const fetchFromRegistry = createFetchFromRegistry(opts)\n  const getResponse = await fetchFromRegistry(packageUrl, {\n    authHeaderValue: authHeader,\n    fullMetadata: true,\n  })\n\n  if (!getResponse.ok) {\n    if (getResponse.status === 404) {\n      throw new PnpmError('PACKAGE_NOT_FOUND', `Package \"${packageName}\" not found in registry`)\n    }\n    throw new PnpmError('REGISTRY_ERROR', `Failed to fetch package info: ${getResponse.status} ${getResponse.statusText}`)\n  }\n\n  const pkg = await getResponse.json() as PackageMeta\n\n  if (!pkg.versions || Object.keys(pkg.versions).length === 0) {\n    throw new PnpmError('NO_VERSIONS', `Package \"${packageName}\" has no versions`)\n  }\n\n  const versionsToUpdate = versionRange\n    ? getVersionsMatchingRange(pkg.versions, versionRange)\n    : Object.keys(pkg.versions)\n\n  if (versionsToUpdate.length === 0) {\n    throw new PnpmError('NO_MATCHING_VERSIONS', `No versions match \"${versionRange}\"`)\n  }\n\n  if (deprecated == null) {\n    const deprecatedVersions = versionsToUpdate.filter((ver) => pkg.versions[ver].deprecated)","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/registry-access/commands/src/deprecation/common.ts#L39-L75","documentation":"Thrown by `updateDeprecation` when the full-metadata fetch for the package fails with any non-404 error status. The command reports the raw HTTP status and statusText because at this point the failure is on the registry or network side — server errors, gateway problems, or a proxy interfering with the metadata request — rather than something wrong with the arguments.","triggerScenarios":"`pnpm deprecate pkg \"msg\"` while registry.npmjs.org returns 500/503 during an incident; a corporate proxy answering the metadata GET with 502; a private registry that errors on `fullMetadata: true` requests.","commonSituations":"npm registry incidents; rate limiting surfaced as 5xx by proxies; private registries with incomplete packument support; flaky VPN/office networks.","solutions":["Retry after a short wait — transient 5xx responses usually clear on their own.","Check the registry status page and basic reachability: `pnpm ping --registry <url>`.","If a proxy is involved, confirm it forwards the metadata GET correctly and inspect its logs.","Try against the public registry with `--registry https://registry.npmjs.org/` to isolate a private-registry problem."],"exampleFix":"# before\npnpm deprecate pkg \"msg\"\n# ERR_PNPM_REGISTRY_ERROR Failed to fetch package info: 503 Service Unavailable\n\n# after\npnpm ping   # wait until this succeeds\npnpm deprecate pkg \"msg\"","handlingStrategy":"retry","validationCode":"// pre-flight: confirm the registry answers before the metadata read\nimport { execSync } from 'child_process'\n\nfunction assertRegistryHealthy (registry = 'https://registry.npmjs.org/'): void {\n  execSync(`pnpm ping --registry ${registry}`, { stdio: 'pipe' })\n}","typeGuard":null,"tryCatchPattern":"async function deprecateWithRetry (run: () => Promise<string>, attempts = 3): Promise<string> {\n  for (let i = 0; i < attempts; i++) {\n    try {\n      return await run()\n    } catch (err) {\n      const code = 'code' in err ? (err as { code: string }).code : ''\n      const msg = err instanceof Error ? err.message : ''\n      if (code !== 'REGISTRY_ERROR' || !/\\b5\\d\\d\\b/.test(msg) || i === attempts - 1) throw err\n      await new Promise((r) => setTimeout(r, 2 ** i * 1000))\n    }\n  }\n  throw new Error('unreachable')\n}","preventionTips":["Treat deprecation as retryable with backoff — the read that fails is a plain GET.","Run `pnpm ping` before scheduled bulk deprecation jobs.","Watch for proxy-induced 502s on large packument fetches (fullMetadata: true)."],"tags":["cli","deprecate","npm-registry","http-5xx","transient"],"backgroundTag":"registry-request-failed","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}