remotion-dev/remotion · error · TypeError

The video frame duration must be non-negative.

Error message

The video frame duration must be non-negative.

What it means

getClippedVideoFrameTiming requires duration to be a finite number >= 0, since it computes the frame's visible span as timestamp + duration. NaN, Infinity or a negative duration throws this TypeError. Zero is allowed (a frame with no visible span simply clips to null).

Source

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

};

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;
	}

	return {
		timestamp: visibleStart - videoStartTimestamp,

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Compute duration as Math.max(0, end - start) and ensure frames are sorted first
  2. Check that the duration source field is populated and in the expected unit
  3. Replace sentinel values like -1/Infinity with real durations or explicit null handling
  4. Validate inputs before calling and skip frames with invalid durations

Example fix

// before
const dur = next.ts - frame.ts; // can be negative if unsorted
// after
const ordered = [...frames].sort((a, b) => a.ts - b.ts);
const dur = Math.max(0, next.ts - frame.ts);
Defensive patterns

Strategy: validation

Validate before calling

const safeDuration = Math.max(0, Number.isFinite(d) ? d : 0);
if (d < 0 || !Number.isFinite(d)) console.warn('Invalid frame duration corrected');

Type guard

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

Try / catch

try {
  const timing = getClippedVideoFrameTiming({timestamp, duration, videoStartTimestamp, videoEndTimestamp});
} catch (err) {
  if (err instanceof TypeError && err.message.includes('duration must be non-negative')) {
    return getClippedVideoFrameTiming({timestamp, duration: 0, videoStartTimestamp, videoEndTimestamp});
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing a negative duration (e.g. end - start computed backwards), NaN from missing metadata, or Infinity from a live-stream style duration placeholder.

Common situations: Computing duration as nextTs - ts with unsorted timestamps yielding negatives, a config where frameDuration was left as -1 'auto', or unit confusion (ms vs seconds producing odd values).

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