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

  1. Coerce the input before passing it: Number(process.env.MAX_RETRIES), and provide a numeric default when it is unset.
  2. If the value comes from config, ensure the source has no quotes around the number (JSON: 3, not "3").
  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

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


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/f4bcb77eefb0b37f. Report an issue: GitHub.