remotion-dev/remotion · error · TypeError

The video frame timestamp must be finite.

Error message

The video frame timestamp must be finite.

What it means

getClippedVideoFrameTiming clips a frame's visibility to the video presentation range and first validates that timestamp is a finite number. Non-finite timestamps (NaN/±Infinity) make clipping math undefined, so a TypeError is thrown early with a precise message.

Source

Thrown at packages/video-matting/src/video-timing.ts:32

		throw new Error('Video frames must be in presentation order.');
	}

	return Math.max(0, rebased);
};

export const getClippedVideoFrameTiming = ({
	timestamp,
	duration,
	videoStartTimestamp,
	videoEndTimestamp,
}: {
	timestamp: number;
	duration: number;
	videoStartTimestamp: number;
	videoEndTimestamp: number;
}): {timestamp: number; duration: number} | null => {
	if (!Number.isFinite(timestamp)) {
		throw new TypeError('The video frame timestamp must be finite.');
	}

	if (!Number.isFinite(duration) || duration < 0) {
		throw new TypeError('The video frame duration must be non-negative.');
	}

	if (
		!Number.isFinite(videoStartTimestamp) ||
		!Number.isFinite(videoEndTimestamp) ||
		videoEndTimestamp < videoStartTimestamp
	) {
		throw new TypeError('The video presentation range is invalid.');
	}

	const visibleStart = Math.max(timestamp, videoStartTimestamp);
	const visibleEnd = Math.min(timestamp + duration, videoEndTimestamp);
	if (visibleEnd <= visibleStart) {
		return null;

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Validate/skip frames with non-finite timestamps before computing clipped timing
  2. Ensure video metadata (start/end) is loaded before scheduling frames
  3. Fix timestamp computation upstream (avoid 0-division, check decoder output)
  4. Wrap in try/catch and treat the frame as missing rather than aborting the whole render

Example fix

// before
const timing = getClippedVideoFrameTiming({timestamp: frame.ts, duration, videoStartTimestamp, videoEndTimestamp});
// after
if (!Number.isFinite(frame.ts)) return null;
const timing = getClippedVideoFrameTiming({timestamp: frame.ts, duration, videoStartTimestamp, videoEndTimestamp});
Defensive patterns

Strategy: validation

Validate before calling

const getClippedSafe = (input) =>
  Number.isFinite(input.timestamp) ? getClippedVideoFrameTiming(input) : null;

Type guard

const isFiniteNumber = (t: unknown): t is number =>
  typeof t === 'number' && Number.isFinite(t);

Try / catch

try {
  const timing = getClippedVideoFrameTiming({timestamp, duration, videoStartTimestamp, videoEndTimestamp});
} catch (err) {
  if (err instanceof TypeError && err.message.includes('timestamp must be finite')) {
    return null; // treat frame as missing
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing a frame timestamp that is NaN or Infinity into getClippedVideoFrameTiming, usually because an upstream demuxer failed or a computed timestamp involved division by zero.

Common situations: Metadata not yet parsed when timing is computed, malformed container headers yielding NaN pts, or hand-built frame lists with missing timestamp fields.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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