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
- Compute duration as Math.max(0, end - start) and ensure frames are sorted first
- Check that the duration source field is populated and in the expected unit
- Replace sentinel values like -1/Infinity with real durations or explicit null handling
- 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
- Sort frames by timestamp before computing inter-frame durations
- Clamp durations with Math.max(0, d)
- Replace sentinel values (-1, Infinity) with real defaults at config load
- Keep duration units consistent (seconds vs milliseconds) across the pipeline
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
- Video frame durations must be non-negative.
- A numeric bitrate must be a positive integer.
- Video timestamps must be finite numbers.
- The video frame timestamp must be finite.
- The video presentation range is invalid.
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/a7cd42cdf2874795.
Report an issue: GitHub.