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

  1. Retry — if caused by a transient bad response, a repeat may succeed.
  2. Inspect the raw response from https://api.github.com/advisories?ecosystem=npm&affects=next&type=reviewed to see the actual shape.
  3. Update the Next.js tooling if the GitHub/npm advisory schema changed.
  4. 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

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


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)