vercel/ai · error · TypeError
Continuation maxAgeMs must be a positive integer.
Error message
Continuation maxAgeMs must be a positive integer.
What it means
resolveCodeModeContinuationSecurity validates the maxAgeMs option and throws a TypeError unless it is a positive, finite integer. maxAgeMs determines how long a signed continuation token remains valid (expiresAtMs = issuedAtMs + maxAgeMs). Values like 0, negative numbers, non-integers, NaN, or Infinity are rejected.
Source
Thrown at packages/code-mode/src/continuation-capability.ts:52
options: CodeModeContinuationSecurityOptions = {},
): ResolvedCodeModeContinuationSecurity {
const signingKey =
options.signingKey === undefined
? Buffer.from(defaultSigningKey)
: typeof options.signingKey === 'string'
? Buffer.from(options.signingKey)
: Buffer.from(options.signingKey);
if (signingKey.byteLength === 0) {
throw new TypeError('Continuation signing key must not be empty.');
}
const maxAgeMs = options.maxAgeMs ?? defaultMaxAgeMs;
if (
!Number.isInteger(maxAgeMs) ||
!Number.isFinite(maxAgeMs) ||
maxAgeMs <= 0
) {
throw new TypeError('Continuation maxAgeMs must be a positive integer.');
}
return { signingKey, maxAgeMs };
}
export function signCodeModeContinuation(
continuation: UnsignedCodeModeContinuation,
security = resolveCodeModeContinuationSecurity(),
): CodeModeContinuation {
const issuedAtMs = Date.now();
const auth: Omit<CodeModeContinuationAuth, 'signature'> = {
alg: SIGNATURE_ALGORITHM,
nonce: randomBytes(16).toString('hex'),
issuedAtMs,
expiresAtMs: issuedAtMs + security.maxAgeMs,
};
return {
...structuredClone(continuation),View on GitHub (pinned to 69428b1f8b)
Solutions
- Pass maxAgeMs as a positive integer in milliseconds, e.g. 60 * 60 * 1000 for 1 hour
- If unsure, omit the option to use the library default (1 hour)
- Validate the value before passing: Number.isInteger(v) && Number.isFinite(v) && v > 0
- Fix the upstream parse producing NaN/0 (e.g. guard Number(config.maxAgeMs) || DEFAULT)
Example fix
// before
setCodeModeContinuationSigningKey(key, { maxAgeMs: Number(process.env.MAX_AGE) }); // NaN
// after
const maxAgeMs = Number.parseInt(process.env.MAX_AGE ?? '', 10);
setCodeModeContinuationSigningKey(key, {
maxAgeMs: Number.isInteger(maxAgeMs) && maxAgeMs > 0 ? maxAgeMs : 60 * 60 * 1000,
}); Defensive patterns
Strategy: validation
Validate before calling
const maxAgeMs = options.maxAgeMs;
if (maxAgeMs !== undefined && (!Number.isInteger(maxAgeMs) || !Number.isFinite(maxAgeMs) || maxAgeMs <= 0)) {
throw new Error(`maxAgeMs must be a positive integer (ms), got: ${String(maxAgeMs)}`);
} Type guard
function isValidMaxAgeMs(v: unknown): v is number {
return typeof v === 'number' && Number.isInteger(v) && Number.isFinite(v) && v > 0;
} Try / catch
try {
resolveCodeModeContinuationSecurity({ signingKey: key, maxAgeMs });
} catch (error) {
if (error instanceof TypeError && /maxAgeMs/.test(error.message)) {
console.error('Bad maxAgeMs value:', maxAgeMs);
return resolveCodeModeContinuationSecurity({ signingKey: key }); // use library default
}
throw error;
} Prevention
- Express durations in milliseconds explicitly (e.g. 60 * 60 * 1000)
- Guard Number(...) parses with Number.isInteger before use
- Never pass user- or config-supplied numbers without validating positivity and integrality
- Omit maxAgeMs to rely on the 1-hour library default
When it happens
Trigger: Passing maxAgeMs: 0 or a negative value to setCodeModeContinuationSigningKey or a security options object; passing NaN/Infinity from a bad numeric parse (Number('abc'), Number.POSITIVE_INFINITY); passing a float like 1500.5; passing a value computed as 0 due to a multiplication by an unset config variable.
Common situations: Config value parsed with parseInt from an empty string yielding NaN; template-driven config where maxAgeMs is a string that got Number()'d to NaN; a default of 0 used for 'unset'; mistaking seconds for milliseconds and passing sub-1ms fractional values.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Invalid argument for parameter output: Invalid output type.
- ACP credentialEnv and credentialBrokering must be configured
- Unsupported ACP protocol version ${JSON.stringify(version)}.
- ACP credentialEnv and credentialBrokering must be configured
- ACP harnessId must be a stable kebab-case identifier; receiv
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/8bf036ae4c304855.
Report an issue: GitHub.