remotion-dev/remotion · error · TypeError

The "times" prop of a loop must be at least 0, but got ${tim

Error message

The "times" prop of a loop must be at least 0, but got ${times}

What it means

Even after `times` is confirmed to be a valid integer, Remotion rejects negative values because a loop cannot repeat a negative number of times. Zero is explicitly allowed (the check is `times < 0`), so the floor is 0 and renders no iterations.

Source

Thrown at packages/core/src/loop/index.tsx:65

	validateDurationInFrames(durationInFrames, {
		component: 'of the <Loop /> component',
		allowFloats: true,
	});

	if (typeof times !== 'number') {
		throw new TypeError(
			`You passed to "times" an argument of type ${typeof times}, but it must be a number.`,
		);
	}

	if (times !== Infinity && times % 1 !== 0) {
		throw new TypeError(
			`The "times" prop of a loop must be an integer, but got ${times}.`,
		);
	}

	if (times < 0) {
		throw new TypeError(
			`The "times" prop of a loop must be at least 0, but got ${times}`,
		);
	}

	const maxTimes = Math.ceil(compDuration / durationInFrames);
	const actualTimes = Math.min(maxTimes, times);
	const style = props.layout === 'none' ? undefined : props.style;
	const maxFrame = durationInFrames * (actualTimes - 1);
	const iteration = Math.floor(currentFrame / durationInFrames);
	const start = iteration * durationInFrames;
	const from = Math.min(start, maxFrame);

	const loopDisplay: LoopDisplay = useMemo(() => {
		return {
			numberOfTimes: Math.min(compDuration / durationInFrames, times),
			startOffset: -from,
			durationInFrames,
		};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Clamp to the minimum: times={Math.max(0, value)}.
  2. Validate/sanitize user input before passing it to <Loop>.
  3. Pass 0 intentionally if rendering nothing is desired.

Example fix

// before
<Loop durationInFrames={30} times={count - extra} />
// after
<Loop durationInFrames={30} times={Math.max(0, count - extra)} />
Defensive patterns

Strategy: validation

Validate before calling

const safeTimes = Math.max(0, Math.round(Number(times)));

Type guard

const isNonNegInt = (v: unknown): v is number =>
  typeof v === 'number' && Number.isInteger(v) && v >= 0;

Prevention

When it happens

Trigger: Passing times={-1}, times={-5}, or any negative integer. Arithmetic such as `baseCount - extra` that can go negative.

Common situations: Subtracting an offset from a base count without clamping; user input controls that allow negative numbers; conditional logic producing a negative result.

Related errors


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