remotion-dev/remotion · error · RangeError

videoEndTimestamp must be greater than or equal to videoStar

Error message

videoEndTimestamp must be greater than or equal to videoStartTimestamp.

What it means

prepareAudio throws a RangeError when videoEndTimestamp is less than videoStartTimestamp, because the audio extraction window would be inverted (negative duration). End must be greater than or equal to start.

Source

Thrown at packages/video-matting/src/prepare-audio.ts:68

	input: Input;
	baseOutput: Output<WebMOutputFormat, BaseTarget>;
	foregroundOutput: Output<WebMOutputFormat, ForegroundTarget>;
	destination: VideoMattingAudioDestination;
	videoStartTimestamp: number;
	videoEndTimestamp: number;
	audioQuality: Quality | null;
	forceTranscode: boolean;
}): Promise<PreparedVideoMattingAudio> => {
	if (!Number.isFinite(videoStartTimestamp)) {
		throw new TypeError('videoStartTimestamp must be a finite number.');
	}

	if (!Number.isFinite(videoEndTimestamp)) {
		throw new TypeError('videoEndTimestamp must be a finite number.');
	}

	if (videoEndTimestamp < videoStartTimestamp) {
		throw new RangeError(
			'videoEndTimestamp must be greater than or equal to videoStartTimestamp.',
		);
	}

	if (typeof forceTranscode !== 'boolean') {
		throw new TypeError('forceTranscode must be a boolean.');
	}

	if (destination === 'none') {
		return {
			prime: () => Promise.resolve(),
			writeAudioUntil: () => Promise.resolve(),
			finishAudio: () => Promise.resolve(),
			cancel: () => Promise.resolve(),
		};
	}

	const audioTrack = await input.getPrimaryAudioTrack();

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Ensure videoEndTimestamp >= videoStartTimestamp by validating/clamping before the call
  2. Check for unit mismatches (ms vs s) and swapped argument order
  3. Clamp end to Math.max(start, Math.min(end, duration))

Example fix

// before
await prepareAudio({videoStartTimestamp: end, videoEndTimestamp: start, ...});
// after
const [s, e] = [Math.min(start, end), Math.max(start, end)];
await prepareAudio({videoStartTimestamp: s, videoEndTimestamp: e, ...});
Defensive patterns

Strategy: validation

Validate before calling

if (videoEndTimestamp < videoStartTimestamp) {
  throw new RangeError('videoEndTimestamp must be >= videoStartTimestamp');
}

Type guard

const isValidRange = (s: number, e: number): boolean =>
  Number.isFinite(s) && Number.isFinite(e) && e >= s;

Try / catch

try {
  await prepareAudio({videoStartTimestamp: s, videoEndTimestamp: e, ...});
} catch (err) {
  if (err instanceof RangeError && err.message.includes('greater than or equal')) {
    [s, e] = [e, s]; // or clamp: e = s
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling prepareAudio where end < start — e.g. swapped arguments, clamping errors, or a segment whose computed start exceeds the video length.

Common situations: Off-by-one or unit mistakes (seconds vs milliseconds) making end smaller than start; reversed trim ranges from UI input; sorting bug producing swapped segment boundaries.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09). Data as JSON: /api/errors/cdbc4cee0e4a2744. Report an issue: GitHub.