remotion-dev/remotion · error · TypeError
maxRetries is NaN
Error message
maxRetries is NaN
What it means
Thrown by validateMaxRetries() in @remotion/lambda when the 'maxRetries' option is the value NaN. maxRetries controls how many times the CLI retries a failed Lambda render/still invocation. Note: in the current source this exact message is effectively unreachable, because the preceding !Number.isFinite(maxRetries) check (validate-retries.ts:10) already rejects NaN (Number.isFinite(NaN) === false) and throws 'maxRetries must be finite, but is NaN' first. You will almost certainly see the finite error instead of this one.
Source
Thrown at packages/lambda/src/shared/validate-retries.ts:15
export function validateMaxRetries(
maxRetries: unknown,
): asserts maxRetries is number {
if (typeof maxRetries !== 'number') {
throw new TypeError(
'maxRetries must be a number, but is ' + JSON.stringify(maxRetries),
);
}
if (!Number.isFinite(maxRetries)) {
throw new TypeError('maxRetries must be finite, but is ' + maxRetries);
}
if (Number.isNaN(maxRetries)) {
throw new TypeError('maxRetries is NaN');
}
if (maxRetries < 0) {
throw new TypeError(`maxRetries cannot be negative but is ${maxRetries}`);
}
if (maxRetries % 1 !== 0) {
throw new TypeError(
`maxRetries should be an integer, but is ${maxRetries}.`,
);
}
}
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Find where maxRetries is sourced and ensure it is a real integer; replace NaN with a sane default like the DEFAULT_MAX_RETRIES constant.
- If parsing from env/config, coerce safely: const maxRetries = Number(process.env.RETRIES); if (!Number.isInteger(maxRetries)) maxRetries = DEFAULT_MAX_RETRIES;
- Note you will likely see 'must be finite, but is NaN' first; treat both as the same root cause.
Example fix
// before
const maxRetries = Number(process.env.RETRIES); // NaN when unset
await renderMediaOnLambda({ compositionId, serveUrl, inputProps, maxRetries });
// after
import {DEFAULT_MAX_RETRIES} from '@remotion/lambda/client';
const parsed = Number(process.env.RETRIES);
const maxRetries = Number.isInteger(parsed) ? parsed : DEFAULT_MAX_RETRIES; Defensive patterns
Strategy: validation
Validate before calling
function safeMaxRetries(raw: unknown, fallback: number): number {
const n = typeof raw === 'number' ? raw : Number(raw);
if (!Number.isFinite(n) || n < 0 || n % 1 !== 0) return fallback;
return n;
}
const maxRetries = safeMaxRetries(process.env.RETRIES, DEFAULT_MAX_RETRIES); Type guard
const isMaxRetries = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0 && v % 1 === 0;
Prevention
- Always source maxRetries from a typed numeric constant (e.g. DEFAULT_MAX_RETRIES), not from an unchecked env parse.
- Run validateMaxRetries early in your own pipeline so the error surfaces before any AWS call is made.
- Treat NaN and 'must be finite' messages as the same defect: an unguarded numeric source.
When it happens
Trigger: Calling renderMediaOnLambda() / renderStillOnLambda() or the `npx remotion lambda render|still --max-retries=<x>` CLI with maxRetries being the literal NaN, e.g. passed via Number(undefined), parseInt(undefined), parseFloat(undefined), or an arithmetic that evaluates to NaN.
Common situations: Reading maxRetries from an env var without validation (parseInt(process.env.RETRIES) when the var is unset), computing it from a malformed config file, or defaulting a missing numeric field to NaN instead of a number.
Related errors
- maxRetries cannot be negative but is ${maxRetries}
- maxRetries should be an integer, but is ${maxRetries}.
- Pass --s3-output-provider-endpoint when using S3 output prov
- Pass --force-bucket-name when using S3 output provider flags
- Pass --out-name when using S3 output provider flags.
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/c5d592b1a79a10cc.
Report an issue: GitHub.