remotion-dev/remotion · error · TypeError
maxRetries must be a number, but is ${JSON.stringify(maxRetr
Error message
maxRetries must be a number, but is ${JSON.stringify(maxRetries)} What it means
Thrown by validateMaxRetries() in @remotion/cloudrun when the maxRetries option is not of type 'number'. The function is a TypeScript assertion (asserts maxRetries is number) used to guard Cloud Run render/deploy retry behavior, and this is the first check in a chain: type, finiteness, NaN, sign, then integrality. It uses JSON.stringify to safely render any non-number value in the message.
Source
Thrown at packages/cloudrun/src/shared/validate-retries.ts:5
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(View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Coerce the input before passing it: Number(process.env.MAX_RETRIES), and provide a numeric default when it is unset.
- If the value comes from config, ensure the source has no quotes around the number (JSON: 3, not "3").
- Add a type guard so a non-number is rejected with your own error before reaching the Cloud Run API.
Example fix
// before
renderMediaOnCloudRun({ ...opts, maxRetries: process.env.MAX_RETRIES });
// after
const retries = Number(process.env.MAX_RETRIES);
renderMediaOnCloudRun({
...opts,
maxRetries: Number.isFinite(retries) ? retries : 1,
}); Defensive patterns
Strategy: validation
Validate before calling
if (typeof maxRetries !== 'number') {
throw new TypeError(`maxRetries must be a number, got ${typeof maxRetries}`);
} Type guard
const isMaxRetries = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && Number.isInteger(v) && v >= 0;
Prevention
- Never pass env vars (strings) straight into numeric options; coerce with Number() first.
- Type render option objects explicitly so non-number maxRetries is a compile error.
- Default optional retry counts to a numeric literal rather than leaving them undefined.
When it happens
Trigger: Calling a Cloud Run render or deploy API with a maxRetries value that is a string, undefined, null, boolean, array, or object. Most commonly the value comes from process.env (always a string) or a JSON config file where the value was quoted.
Common situations: Reading retries from an environment variable without coercing with Number(); loading options from a parsed JSON/YAML config where maxRetries was written as "3" instead of 3; passing a value typed as string | number without narrowing.
Related errors
- "serveURL" parameter must be a string, but is ${JSON.stringi
- "serviceName" parameter must be a string, but is ${JSON.stri
- The 'siteName' argument must be a string if provided, but is
- Bucket creation is required, but no region has been passed.
- 'bucketName' must be a string, but is ${JSON.stringify(bucke
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/f4bcb77eefb0b37f.
Report an issue: GitHub.