vercel/next.js · error · Error
Could not check for security updates.
Error message
Could not check for security updates.
What it means
affectedRanges validates each advisory object from GitHub before extracting vulnerable ranges and throws this when an advisory is not the expected shape: missing/falsy object, `vulnerabilities` not an array, or `withdrawn_at` key absent. GitHub's advisory schema is trusted only after these checks; anything else aborts the security check rather than producing a wrong 'safe' verdict.
Solutions
- Retry — if caused by a transient bad response, a repeat may succeed.
- Inspect the raw response from https://api.github.com/advisories?ecosystem=npm&affects=next&type=reviewed to see the actual shape.
- Update the Next.js tooling if the GitHub/npm advisory schema changed.
- Remove any proxy or interceptor that rewrites API responses.
Example fix
// before
const advisories = await res.json()
affectedRanges(advisories) // throws on shape mismatch
// after
const advisories = await res.json()
if (!Array.isArray(advisories)) throw new Error('bad advisories payload')
affectedRanges(advisories.filter(a => a && Array.isArray(a.vulnerabilities))) Defensive patterns
Strategy: type-guard
Validate before calling
const res = await fetch('https://api.github.com/advisories?ecosystem=npm&affects=next&type=reviewed')
const advisories = await res.json()
if (!Array.isArray(advisories) || advisories.some(a => !a || !Array.isArray(a.vulnerabilities) || !('withdrawn_at' in a))) {
throw new Error('GitHub advisories payload has unexpected shape')
} Type guard
function isAdvisory(value: unknown): value is Advisory {
return typeof value === 'object' && value !== null
&& Array.isArray((value as any).vulnerabilities)
&& 'withdrawn_at' in value
} Try / catch
try {
const ref = await getSecurityAdvisory(version)
} catch (error) {
if ((error as Error).message === 'Could not check for security updates.') {
// advisory schema mismatch — check GitHub API changelog / pin tooling version
}
throw error
} Prevention
- Keep the Next.js tooling updated when GitHub or npm change advisory schemas
- Don't route api.github.com through rewriting proxies
- Validate advisory payloads yourself in wrapper scripts before trusting 'safe' verdicts
When it happens
Trigger: readGitHubAdvisories() or readNpmAdvisories() output fed to affectedRanges where an element is null, lacks a vulnerabilities array, or has no withdrawn_at field — e.g. a GitHub API schema change, a proxy injecting a different payload, or an npm bulk endpoint item shape change.
Common situations: GitHub advisories API returning an unexpected envelope; mirror/CDN rewriting responses; npm's bulk advisory endpoint changing its item format; version skew where the tooling expects a newer/older schema.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Could not check Next.js security advisories. Continuing…
- Next.js is affected by an active advisory.
- No safe Next.js update is currently available.
AI-assisted analysis of vercel/next.js@34433fd12e (2026-09-20).
Data as JSON: /api/errors/8e58f83ddb8b776a.
Report an issue: GitHub.
Appendix: source
Thrown at packages/next/src/lib/upgrade/prepare-upgrade.ts:249
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[] = []
for (const advisory of advisories) {
if (
!advisory ||
!Array.isArray(advisory.vulnerabilities) ||
!('withdrawn_at' in advisory)
) {
throw new Error('Could not check for security updates.')
}
if (advisory.withdrawn_at) {
continue
}
for (const finding of advisory.vulnerabilities) {
if (
!finding.package ||
typeof finding.package.name !== 'string' ||
typeof finding.package.ecosystem !== 'string'
) {
throw new Error('Could not check for security updates.')
}
if (
finding.package.ecosystem !== 'npm' ||
finding.package.name !== 'next'View on GitHub (pinned to 34433fd12e)