{"record":{"id":"12fc2401c2754260","repo":"nextauthjs/next-auth","slug":"option-maxage-is-invalid-options-maxage","errorCode":null,"errorMessage":"option maxAge is invalid: ${options.maxAge}","messagePattern":"option maxAge is invalid: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/lib/vendored/cookie.ts","lineNumber":276,"sourceCode":"): string {\n  const enc = options?.encode || encodeURIComponent\n\n  if (!cookieNameRegExp.test(name)) {\n    throw new TypeError(`argument name is invalid: ${name}`)\n  }\n\n  const value = enc(val)\n\n  if (!cookieValueRegExp.test(value)) {\n    throw new TypeError(`argument val is invalid: ${val}`)\n  }\n\n  let str = name + \"=\" + value\n  if (!options) return str\n\n  if (options.maxAge !== undefined) {\n    if (!Number.isInteger(options.maxAge)) {\n      throw new TypeError(`option maxAge is invalid: ${options.maxAge}`)\n    }\n\n    str += \"; Max-Age=\" + options.maxAge\n  }\n\n  if (options.domain) {\n    if (!domainValueRegExp.test(options.domain)) {\n      throw new TypeError(`option domain is invalid: ${options.domain}`)\n    }\n\n    str += \"; Domain=\" + options.domain\n  }\n\n  if (options.path) {\n    if (!pathValueRegExp.test(options.path)) {\n      throw new TypeError(`option path is invalid: ${options.path}`)\n    }\n","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/lib/vendored/cookie.ts#L258-L294","documentation":"The vendored cookie `serialize` requires options.maxAge, when defined, to be an integer number of seconds (which is what the Max-Age attribute supports). Non-integer values such as floats, NaN, or values derived from a Date are rejected with a TypeError.","triggerScenarios":"Calling serialize(name, val, { maxAge }) where maxAge is not an integer — e.g. a float like 3600.5, NaN from a failed parse, Infinity, or milliseconds from Date.now()/getTime() math.","commonSituations":"Passing milliseconds (Date.now diff) instead of seconds; computing expiry with non-integer division; reading maxAge from config/env where parseInt failed and produced NaN; TypeScript types loose enough (any) to let a Date or string slip in.","solutions":["Pass maxAge as an integer number of SECONDS: `maxAge: 60 * 60 * 24` for one day.","Convert from milliseconds with Math.floor(ms / 1000) before passing it.","Guard the value: only set maxAge when Number.isInteger(maxAge), otherwise omit or fix it.","Fix env/config parsing so the numeric value is valid (e.g. Number(process.env.X) with a fallback)."],"exampleFix":"// before\nconst maxAge = expiry.getTime() - Date.now() // milliseconds, non-integer\nserialize(\"sid\", token, { maxAge })\n// after\nconst maxAge = Math.floor((expiry.getTime() - Date.now()) / 1000)\nserialize(\"sid\", token, { maxAge })","handlingStrategy":"validation","validationCode":"if (maxAge !== undefined && !Number.isInteger(maxAge)) {\n  throw new Error(`maxAge must be an integer number of seconds, got: ${maxAge}`)\n}","typeGuard":"function isValidMaxAge(v: unknown): v is number {\n  return typeof v === \"number\" && Number.isInteger(v)\n}","tryCatchPattern":"try {\n  return serialize(name, value, { ...opts, maxAge })\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes(\"option maxAge is invalid\")) {\n    return serialize(name, value, { ...opts, maxAge: Math.floor(Number(maxAge)) })\n  }\n  throw e\n}","preventionTips":["Always express maxAge in SECONDS via integer arithmetic (e.g. 60 * 60 * 24)","Convert Date math with Math.floor((expiryMs - Date.now()) / 1000)","Validate env/config numbers with Number() plus an integer check before use","Type option objects strictly (maxAge?: number) instead of any to catch Dates/strings at compile time"],"tags":["cookie","validation","maxage","typeerror"],"backgroundTag":"invalid-cookie-maxage","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}