remotion-dev/remotion · error · TypeError

Video frame durations must be non-negative.

Error message

Video frame durations must be non-negative.

What it means

getVideoProcessingProgress accumulates processed frame durations to compute progress against the total video duration. Each frame duration must be a finite number >= 0; NaN, Infinity or negative values throw this TypeError, since summing them would corrupt the progress metric.

Source

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

	return {
		timestamp: visibleStart - videoStartTimestamp,
		duration: visibleEnd - visibleStart,
	};
};

export const getVideoProcessingProgress = ({
	timestamp,
	duration,
	firstVideoTimestamp,
	durationInSeconds,
}: {
	timestamp: number;
	duration: number;
	firstVideoTimestamp: number;
	durationInSeconds: number;
}): {processedDurationInSeconds: number; progress: number} => {
	if (!Number.isFinite(duration) || duration < 0) {
		throw new TypeError('Video frame durations must be non-negative.');
	}

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

	const rebasedTimestamp = rebaseVideoTimestamp({
		timestamp,
		firstVideoTimestamp,
	});
	const processedDurationInSeconds = Math.min(
		durationInSeconds,
		Math.max(0, rebasedTimestamp + duration),
	);

	return {
		processedDurationInSeconds,
		progress:

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Sanitize frame durations: Math.max(0, finite value) before accumulating
  2. Sort frames by timestamp so inter-frame durations are non-negative
  3. Ensure total durationInSeconds is a real finite value before computing progress
  4. Skip invalid frames in progress accounting instead of passing them through

Example fix

// before
const p = getVideoProcessingProgress({timestamp, duration: frame.dur, firstVideoTimestamp, durationInSeconds});
// after
const dur = Number.isFinite(frame.dur) ? Math.max(0, frame.dur) : 0;
const p = getVideoProcessingProgress({timestamp, duration: dur, firstVideoTimestamp, durationInSeconds});
Defensive patterns

Strategy: validation

Validate before calling

const safeFrameDuration = (d: number) => (Number.isFinite(d) && d >= 0 ? d : 0);
const total = frames.reduce((acc, f) => acc + safeFrameDuration(f.dur), 0);

Type guard

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

Try / catch

try {
  const {progress} = getVideoProcessingProgress({timestamp, duration, firstVideoTimestamp, durationInSeconds});
} catch (err) {
  if (err instanceof TypeError && err.message.includes('durations must be non-negative')) {
    console.warn('Invalid frame duration; progress may be inaccurate');
    return {processedDurationInSeconds: 0, progress: 0};
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling getVideoProcessingProgress with a frame duration that is NaN, Infinity, or negative — typically from unsorted frames (next.ts - ts < 0), failed metadata parse, or Infinity placeholders.

Common situations: Progress reporting over frames decoded out of order, live/unbounded durations passed in, or duration fields left undefined and coerced to NaN by arithmetic.

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