vercel/next.js · error · Error

Invalid revalidate value "${revalidateVal}" on "${route}", m

Error message

Invalid revalidate value "${revalidateVal}" on "${route}", must be a non-negative number or false

What it means

Thrown by validateRevalidate when a route's revalidate export or a fetch() revalidate option is a value that is neither false, Infinity, undefined, nor a non-negative finite number. The revalidate contract requires a non-negative number or false to define ISR caching behavior.

Source

Thrown at packages/next/src/server/lib/patch-fetch.ts:115

export function validateRevalidate(
  revalidateVal: unknown,
  route: string
): undefined | number {
  try {
    let normalizedRevalidate: number | undefined = undefined

    if (revalidateVal === false || revalidateVal === Infinity) {
      // Unlike Infinity, INFINITE_CACHE survives JSON serialization (e.g. in
      // the fetch cache).
      normalizedRevalidate = INFINITE_CACHE
    } else if (
      typeof revalidateVal === 'number' &&
      !isNaN(revalidateVal) &&
      revalidateVal > -1
    ) {
      normalizedRevalidate = revalidateVal
    } else if (typeof revalidateVal !== 'undefined') {
      throw new Error(
        `Invalid revalidate value "${revalidateVal}" on "${route}", must be a non-negative number or false`
      )
    }
    return normalizedRevalidate
  } catch (err: any) {
    // handle client component error from attempting to check revalidate value
    if (err instanceof Error && err.message.includes('Invalid revalidate')) {
      throw err
    }
    return undefined
  }
}

export function validateTags(tags: any[], description: string) {
  const validTags: string[] = []
  const invalidTags: Array<{
    tag: any
    reason: string

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Change the revalidate value to a literal non-negative number (e.g. 60) or false.
  2. Remove quotes around the value: revalidate = 60, not '60'.
  3. If computing revalidate at runtime, coerce with Number() and validate it is finite and >= 0 before exporting.
  4. For fetch(), pass { revalidate: 3600 } or { revalidate: false }, never a string or null.

Example fix

// before
export const revalidate = '60' // string -> throws

// after
export const revalidate = 60 // non-negative number
Defensive patterns

Strategy: validation

Validate before calling

function validateRevalidate(v: unknown): number | false {
  if (v === false || v === Infinity) return false
  if (typeof v === 'number' && !isNaN(v) && v >= 0) return v
  throw new Error('revalidate must be a non-negative number or false')
}

Type guard

function isValidRevalidate(v: unknown): v is number | false {
  return v === false || (typeof v === 'number' && !isNaN(v) && v >= 0)
}

Try / catch

null

Prevention

When it happens

Trigger: A page exports `export const revalidate = '60'` (string), `revalidate = -1`, `revalidate = null`, or a fetch is called with `{ revalidate: 'abc' }`. validateRevalidate normalizes then throws for anything outside the allowed set.

Common situations: Passing revalidate as a string (common copy-paste mistake), using a negative number, NaN, or a boolean true. Also happens when revalidate is computed dynamically and yields an unexpected type.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/aeeb20f6e22bba0f. Report an issue: GitHub.