remotion-dev/remotion · error · TypeError

endAt prop must be greater than startFrom prop.

Error message

endAt prop must be greater than startFrom prop.

What it means

validateStartFromProps enforces that endAt must be greater than startFrom, otherwise the requested playback window is empty or inverted. This check runs after individual type/range checks so both values are known to be valid numbers.

Source

Thrown at packages/core/src/validate-start-from-props.ts:42

		if (typeof endAt !== 'number') {
			throw new TypeError(
				`type of endAt prop must be a number, instead got type ${typeof endAt}.`,
			);
		}

		if (isNaN(endAt)) {
			throw new TypeError('endAt prop can not be NaN.');
		}

		if (endAt <= 0) {
			throw new TypeError(
				`endAt must be a positive number, instead got ${endAt}.`,
			);
		}
	}

	if ((endAt as number) < (startFrom as number)) {
		throw new TypeError('endAt prop must be greater than startFrom prop.');
	}
};

export const validateTrimProps = (
	trimBefore: number | undefined,
	trimAfter: number | undefined,
) => {
	if (typeof trimBefore !== 'undefined') {
		if (typeof trimBefore !== 'number') {
			throw new TypeError(
				`type of trimBefore prop must be a number, instead got type ${typeof trimBefore}.`,
			);
		}

		if (isNaN(trimBefore) || trimBefore === Infinity) {
			throw new TypeError('trimBefore prop can not be NaN or Infinity.');
		}

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure endAt is strictly greater than startFrom: startFrom={50} endAt={200}.
  2. If computing dynamically, assert order before rendering: endAt = Math.max(endAt, startFrom + 1).
  3. Swap the two values if they were reversed.
  4. Migrate to trimBefore/trimAfter (same ordering constraint applies: trimAfter must exceed trimBefore).

Example fix

// before
<Audio src={src} startFrom={100} endAt={50} />
// after
<Audio src={src} trimBefore={50} trimAfter={100} />
Defensive patterns

Strategy: validation

Validate before calling

if (
  startFrom !== undefined &&
  endAt !== undefined &&
  endAt <= startFrom
) {
  throw new Error('endAt must be greater than startFrom');
}

Type guard

const isValidWindow = (
  startFrom: unknown,
  endAt: unknown,
): boolean =>
  typeof startFrom === 'number' &&
  typeof endAt === 'number' &&
  Number.isFinite(startFrom) &&
  Number.isFinite(endAt) &&
  endAt > startFrom;

Prevention

When it happens

Trigger: Passing both startFrom and endAt where endAt <= startFrom, e.g. startFrom={100} endAt={50}, or computed values where the trim window inverts.

Common situations: Swapping startFrom and endAt by mistake; computing both from a dynamic source where the ordering assumption breaks; off-by-one when startFrom and endAt are derived from separate timestamps.

Related errors


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