remotion-dev/remotion · error · TypeError

durationInFrames must be positive, but got ${durationInFrame

Error message

durationInFrames must be positive, but got ${durationInFrames}

What it means

Thrown by <Sequence> when durationInFrames is a number but is <= 0 (zero or negative). A sequence with non-positive duration is meaningless on the timeline and would cause downstream math (parent-clamping, frame-window calculation) to produce empty or inverted ranges. The check fires after the type check.

Source

Thrown at packages/core/src/Sequence.tsx:213

		bottom: resolvedCropBottom,
	} = resolveSequenceCrop(cropProps);
	// @ts-expect-error
	if (layout === 'none' && typeof other.style !== 'undefined') {
		throw new TypeError(
			'If layout="none", you may not pass a style. Passed: ' +
				// @ts-expect-error
				JSON.stringify(other.style),
		);
	}

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

	if (durationInFrames <= 0) {
		throw new TypeError(
			`durationInFrames must be positive, but got ${durationInFrames}`,
		);
	}

	if (typeof from !== 'number') {
		throw new TypeError(
			`You passed to the "from" props of your <Sequence> an argument of type ${typeof from}, but it must be a number.`,
		);
	}

	if (!Number.isFinite(from)) {
		throw new TypeError(
			`The "from" prop of a sequence must be finite, but got ${from}.`,
		);
	}

	if (typeof trimBefore !== 'number') {
		throw new TypeError(

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass a positive integer: `durationInFrames={30}` (at least 1).
  2. Clamp computed values: `durationInFrames={Math.max(1, Math.round(value))}`.
  3. Defer mounting until duration is known and positive: `{d > 0 && <Sequence durationInFrames={d} />}`.
  4. Audit default props and config loaders to ensure duration is never 0 or negative.

Example fix

// before
<Sequence durationInFrames={state.loaded ? state.duration : 0} />
// after
{state.loaded && state.duration > 0 && (
  <Sequence durationInFrames={Math.max(1, Math.round(state.duration))} />
)}
Defensive patterns

Strategy: validation

Validate before calling

if (typeof durationInFrames === 'number' && durationInFrames <= 0) {
  throw new RangeError(`durationInFrames must be positive; got ${durationInFrames}`);
}

Type guard

const isPositive = (n: unknown): n is number =>
  typeof n === 'number' && n > 0 && Number.isFinite(n);

Prevention

When it happens

Trigger: Passing `durationInFrames={0}`, `durationInFrames={-10}`, or a computed value that crosses zero; passing Infinity is allowed at runtime here but should be avoided.

Common situations: Animating duration from a starting value of 0; computing duration from a subtraction that can go negative; defaulting to 0 before metadata loads.

Related errors


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