vercel/next.js · error · Error

Could not determine a safe Next.js version.

Error message

Could not determine a safe Next.js version.

What it means

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.

Solutions

  1. Retry the command — likely a transient registry or proxy issue.
  2. Fetch https://registry.npmjs.org/next directly with curl and confirm the `versions` key exists.
  3. Bypass or fix any proxy/mirror that rewrites the packument response.
  4. Report the issue if npm's registry response format changed.

Example fix

// before
const data = await fetch('https://registry.npmjs.org/next').then(r => r.json())
// after
const data = await fetch('https://registry.npmjs.org/next').then(r => r.json())
if (!data?.versions) throw new Error('Registry packument missing versions map')
Defensive patterns

Strategy: validation

Validate before calling

const packument = await fetch('https://registry.npmjs.org/next').then(r => r.json())
if (!packument || typeof packument !== 'object' || !packument.versions) {
  throw new Error('Registry packument is missing the versions map')
}

Type guard

function hasVersionsMap(value: unknown): value is { versions: Record<string, { version: string }> } {
  return typeof value === 'object' && value !== null && 'versions' in value && typeof (value as any).versions === 'object'
}

Try / catch

try {
  const prep = await prepareUpgrade(dir, 'security')
} catch (error) {
  if ((error as Error).message.includes('Could not determine a safe Next.js version')) {
    // registry document unusable — verify registry connectivity/mirror
  }
  throw error
}

Prevention

When it happens

Trigger: 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).

Common situations: A corporate proxy or cache serving a JSON error object instead of the packument; npm registry partial outage; a future npm registry format change.

Related errors


AI-assisted analysis of vercel/next.js@34433fd12e (2026-09-20). Data as JSON: /api/errors/91a951dc1ba3796d. Report an issue: GitHub.

Appendix: source

Thrown at packages/next/src/lib/upgrade/prepare-upgrade.ts:224

      cause: error,
    })
  }
}

function parseReleases(value: unknown): SecuritySnapshot['releases'] {
  const data = value as {
    versions:
      | Record<
          string,
          {
            version: string
          }
        >
      | undefined
  }

  if (!data?.versions) {
    throw new Error('Could not determine a safe Next.js version.')
  }

  return Object.entries(data.versions).flatMap(([version, metadata]) => {
    if (!semver.valid(version) || semver.prerelease(version)) {
      return []
    }

    if (metadata.version !== version) {
      throw new Error('Could not determine a safe Next.js version.')
    }

    return [{ version }]
  })
}

function affectedRanges(advisories: Advisory[]): string[] {
  const ranges: string[] = []

View on GitHub (pinned to 34433fd12e)