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