remotion-dev/remotion · error · TypeError

Video timestamps must be finite numbers.

Error message

Video timestamps must be finite numbers.

What it means

rebaseVideoTimestamp shifts a frame timestamp relative to the first video timestamp and requires both to be finite numbers; NaN, Infinity or -Infinity triggers this TypeError. It protects the presentation-order check and downstream timing math from undefined behavior caused by non-finite values.

Source

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

export const rebaseVideoTimestamp = ({
	timestamp,
	firstVideoTimestamp,
}: {
	timestamp: number;
	firstVideoTimestamp: number;
}): number => {
	if (!Number.isFinite(timestamp) || !Number.isFinite(firstVideoTimestamp)) {
		throw new TypeError('Video timestamps must be finite numbers.');
	}

	const rebased = timestamp - firstVideoTimestamp;
	if (rebased < -Number.EPSILON * 16) {
		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;

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Verify the demuxer/decoder supplies finite timestamps; log frames before rebasing
  2. Ensure firstVideoTimestamp is initialized from a real frame before processing subsequent ones
  3. Guard the caller: skip frames with non-finite timestamps instead of passing them through
  4. Fix fps/duration math so no division by zero yields NaN

Example fix

// before
const ts = rebasedTimestamp({timestamp: frame.ts, firstVideoTimestamp});
// after
if (!Number.isFinite(frame.ts) || !Number.isFinite(firstVideoTimestamp)) return; // skip bad frame
const ts = rebasedTimestamp({timestamp: frame.ts, firstVideoTimestamp});
Defensive patterns

Strategy: validation

Validate before calling

const canRebase = (ts: number, first: number) =>
  Number.isFinite(ts) && Number.isFinite(first);
if (!canRebase(frame.ts, firstVideoTimestamp)) return null;

Type guard

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

Try / catch

try {
  const ts = rebasedTimestamp({timestamp: frame.ts, firstVideoTimestamp});
} catch (err) {
  if (err instanceof TypeError && err.message.includes('finite')) {
    console.warn('Skipping frame with non-finite timestamp');
    return null;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling rebaseVideoTimestamp (directly or via rebasedTimestamp) with timestamp or firstVideoTimestamp being NaN/Infinity — typically from a failed media metadata parse, a missing duration field, or a divide-by-zero producing NaN upstream.

Common situations: Demuxer emitting NaN timestamps for unparseable packets, dividing by fps=0 to compute timestamps, or uninitialized firstVideoTimestamp when metadata hasn't loaded yet.

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/a5e1ad517127dc25. Report an issue: GitHub.