{"record":{"id":"56aa70df0bda1a85","repo":"vercel/next.js","slug":"could-not-determine-the-latest-stable-next-js-version","errorCode":null,"errorMessage":"Could not determine the latest stable Next.js version.","messagePattern":"Could not determine the latest stable Next\\.js version\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/next/src/lib/upgrade/prepare-upgrade.ts","lineNumber":64,"sourceCode":"\n  // TODO: Handle prereleases\n  if (semver.prerelease(installedVersion)) {\n    throw new Error(\n      'AI upgrades are not available for prerelease versions of Next.js yet.'\n    )\n  }\n\n  if (targetRequest === 'latest' || targetRequest === 'future') {\n    const url = `${NPM_REGISTRY}next/latest`\n    const { value } = await fetchJSON(url)\n    const release = value as { version: string } | null\n\n    if (\n      !release ||\n      !semver.valid(release.version) ||\n      semver.prerelease(release.version)\n    ) {\n      throw new Error('Could not determine the latest stable Next.js version.')\n    }\n\n    const targetVersion =\n      targetRequest === 'future' && semver.gt(installedVersion, release.version)\n        ? installedVersion\n        : release.version\n\n    if (\n      targetRequest === 'latest' &&\n      semver.eq(release.version, installedVersion)\n    ) {\n      return {\n        status: 'unaffected',\n        reason: `Next.js ${installedVersion} is already the latest stable release.`,\n      }\n    }\n\n    if (","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/vercel/next.js/blob/34433fd12ee8074ea3f47af9f36255c7390d0301/packages/next/src/lib/upgrade/prepare-upgrade.ts#L46-L82","documentation":"For 'latest'/'future' policies the CLI fetches https://registry.npmjs.org/next/latest and validates the dist-tag's version field. If the response is missing, the version is invalid semver, or it is itself a prerelease, the CLI cannot name a trustworthy target and throws. Note network failures surface earlier as 'Could not fetch upgrade metadata'; this error means the response arrived but its shape/value was unusable.","triggerScenarios":"registry.npmjs.org returns a malformed or non-JSON 'latest' payload; a proxy/mirror serves an altered response; a hypothetical registry state where the latest dist-tag points to a canary or empty version.","commonSituations":"Corporate npm mirrors/private registries that do not proxy the 'latest' dist-tag correctly; transient registry incidents; DNS hijacking or captive portals returning HTML.","solutions":["Retry — this is often a transient registry issue","Verify the dist-tag: npm view next version (should print a stable semver)","Point npm at the official registry (check .npmrc registry= and proxy settings) if using a mirror","Check npm status (status.npmjs.org) for ongoing incidents"],"exampleFix":"// before (.npmrc)\nregistry=https://internal-mirror.example/api/npm/registry\n// after\nregistry=https://registry.npmjs.org/","handlingStrategy":"retry","validationCode":"const res = await fetch('https://registry.npmjs.org/next/latest')\nconst data = await res.json()\nconst semver = require('semver')\nif (!data?.version || !semver.valid(data.version) || semver.prerelease(data.version)) {\n  console.error('Registry latest dist-tag unusable; check registry/proxy')\n}","typeGuard":null,"tryCatchPattern":"try {\n  await prepareUpgrade(dir, 'latest')\n} catch (e) {\n  if (e.message.includes('latest stable Next.js version')) {\n    await retry(() => prepareUpgrade(dir, 'latest'), { retries: 3 })\n  }\n}","preventionTips":["Point npm at the official registry or a correctly-proxying mirror","Check npm status page during incidents","Retry transient failures before reporting"],"tags":["nextjs","upgrade","npm-registry","network"],"backgroundTag":"unexpected-api-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"}