{"record":{"id":"91a951dc1ba3796d","repo":"vercel/next.js","slug":"could-not-determine-a-safe-next-js-version","errorCode":null,"errorMessage":"Could not determine a safe Next.js version.","messagePattern":"Could not determine a safe Next\\.js version\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/next/src/lib/upgrade/prepare-upgrade.ts","lineNumber":224,"sourceCode":"      cause: error,\n    })\n  }\n}\n\nfunction parseReleases(value: unknown): SecuritySnapshot['releases'] {\n  const data = value as {\n    versions:\n      | Record<\n          string,\n          {\n            version: string\n          }\n        >\n      | undefined\n  }\n\n  if (!data?.versions) {\n    throw new Error('Could not determine a safe Next.js version.')\n  }\n\n  return Object.entries(data.versions).flatMap(([version, metadata]) => {\n    if (!semver.valid(version) || semver.prerelease(version)) {\n      return []\n    }\n\n    if (metadata.version !== version) {\n      throw new Error('Could not determine a safe Next.js version.')\n    }\n\n    return [{ version }]\n  })\n}\n\nfunction affectedRanges(advisories: Advisory[]): string[] {\n  const ranges: string[] = []\n","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/vercel/next.js/blob/34433fd12ee8074ea3f47af9f36255c7390d0301/packages/next/src/lib/upgrade/prepare-upgrade.ts#L206-L242","documentation":"parseReleases validates the npm registry document for the `next` package and throws this when the expected `versions` map is missing entirely. Without the version list it cannot enumerate candidate safe releases, so it refuses to guess.","triggerScenarios":"readSecuritySnapshot() fetches https://registry.npmjs.org/next and passes the body to parseReleases; the JSON either lacks a `versions` object (unexpected registry response, cached/proxied error page parsed as JSON, API shape change).","commonSituations":"A corporate proxy or cache serving a JSON error object instead of the packument; npm registry partial outage; a future npm registry format change.","solutions":["Retry the command — likely a transient registry or proxy issue.","Fetch https://registry.npmjs.org/next directly with curl and confirm the `versions` key exists.","Bypass or fix any proxy/mirror that rewrites the packument response.","Report the issue if npm's registry response format changed."],"exampleFix":"// before\nconst data = await fetch('https://registry.npmjs.org/next').then(r => r.json())\n// after\nconst data = await fetch('https://registry.npmjs.org/next').then(r => r.json())\nif (!data?.versions) throw new Error('Registry packument missing versions map')","handlingStrategy":"validation","validationCode":"const packument = await fetch('https://registry.npmjs.org/next').then(r => r.json())\nif (!packument || typeof packument !== 'object' || !packument.versions) {\n  throw new Error('Registry packument is missing the versions map')\n}","typeGuard":"function hasVersionsMap(value: unknown): value is { versions: Record<string, { version: string }> } {\n  return typeof value === 'object' && value !== null && 'versions' in value && typeof (value as any).versions === 'object'\n}","tryCatchPattern":"try {\n  const prep = await prepareUpgrade(dir, 'security')\n} catch (error) {\n  if ((error as Error).message.includes('Could not determine a safe Next.js version')) {\n    // registry document unusable — verify registry connectivity/mirror\n  }\n  throw error\n}","preventionTips":["Avoid registry mirrors/proxies that rewrite packuments","Verify `npm view next versions` works before running upgrade tooling","Pin the official registry URL in .npmrc for CI"],"tags":["npm","registry","validation","unexpected-response"],"backgroundTag":"unexpected-response-shape","analyzedSha":"34433fd12ee8074ea3f47af9f36255c7390d0301","analyzedAt":"2026-09-20T18:20:20.576Z","contentChangedAt":"2026-09-20T18:20:20.576Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}