{"record":{"id":"0b32e40707b08b77","repo":"vercel/next.js","slug":"invalid-name-provided-expected-a-finite-numb","errorCode":null,"errorMessage":"Invalid \"${name}\" provided, expected a finite number of seconds or Infinity, received ${value}","messagePattern":"Invalid \"(.+?)\" provided, expected a finite number of seconds or Infinity, received (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/next/src/server/config.ts","lineNumber":128,"sourceCode":"    }\n  }\n\n  return [warnings, fatalErrors]\n}\n\n// Infinity means \"never\", but turns into null when serialized as JSON (e.g.\n// for build workers or the prerender manifest), unlike INFINITE_CACHE.\nfunction normalizeInfiniteDuration(\n  value: number | undefined,\n  name: string\n): number | undefined {\n  if (value === undefined || Number.isFinite(value)) {\n    return value\n  }\n  if (value === Infinity) {\n    return INFINITE_CACHE\n  }\n  throw new Error(\n    `Invalid \"${name}\" provided, expected a finite number of seconds or Infinity, received ${value}`\n  )\n}\n\nexport function warnOptionHasBeenDeprecated(\n  config: NextConfig,\n  nestedPropertyKey: string,\n  reason: string,\n  silent: boolean\n): boolean {\n  let hasWarned = false\n  if (!silent) {\n    let current = config\n    let found = true\n    const nestedPropertyKeys = nestedPropertyKey.split('.')\n    for (const key of nestedPropertyKeys) {\n      if ((current as any)[key] !== undefined) {\n        current = (current as any)[key]","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/packages/next/src/server/config.ts#L110-L146","documentation":"Thrown by normalizeInfiniteDuration() when a duration config value is neither a finite number nor Infinity. The function accepts undefined or finite numbers as-is and maps Infinity to INFINITE_CACHE; anything else (NaN, a string, -Infinity, an object) is rejected. It validates expireTime and experimental.staleTimes.dynamic/static.","triggerScenarios":"next.config.js sets expireTime or experimental.staleTimes.dynamic/static to a non-finite, non-Infinity value (e.g. a string like '60', NaN, -Infinity). During config normalization (config.ts:1375-1386), normalizeInfiniteDuration throws.","commonSituations":"Passing a string instead of a number to a duration config; computing a value that yields NaN (e.g. undefined arithmetic); using -Infinity by mistake; copy-pasting a config with quoted numbers.","solutions":["Provide a finite number of seconds (e.g. 60) or Infinity for 'never'.","Ensure the value is a number type, not a string -- remove quotes.","If computing the value, guard against NaN/undefined before assignment.","Avoid -Infinity; use 0 for immediate expiry or Infinity for never."],"exampleFix":"// before\n// module.exports = { expireTime: '3600', experimental: { staleTimes: { dynamic: -Infinity } } }\n\n// after\n// module.exports = { expireTime: 3600, experimental: { staleTimes: { dynamic: 60 } } }","handlingStrategy":"type-guard","validationCode":"// Validate duration config before assigning.\nfunction asDuration(v: unknown): number | undefined {\n  if (v === undefined) return undefined\n  if (v === Infinity) return Infinity\n  if (typeof v === 'number' && Number.isFinite(v)) return v\n  throw new Error('duration must be a finite number or Infinity')\n}","typeGuard":"function isValidDuration(v: unknown): v is number | undefined {\n  return v === undefined || v === Infinity || (typeof v === 'number' && Number.isFinite(v))\n}","tryCatchPattern":null,"preventionTips":["Use numeric literals (not strings) for duration configs.","Guard computed values against NaN before assignment.","Use Infinity for 'never', not -Infinity or a huge string.","Type your config to prevent non-number values."],"tags":["configuration","next-config","validation","cache"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}