remotion-dev/remotion · error · Error

The primary video track contains no presentable decodable fr

Error message

The primary video track contains no presentable decodable frames.

What it means

After configuring a CanvasSink over the video track, the first iterator.next() returned done — the track yielded no decodable, presentable frames in the [videoStartTimestamp, videoEndTimestamp] range. Even though the track metadata looked valid, no frame could actually be produced, so the library throws.

Source

Thrown at packages/video-matting/src/separate-video-layers.ts:398

				};

				options.signal?.addEventListener('abort', onAbort, {once: true});

				try {
					const canvasSink = new CanvasSink(videoTrack, {
						alpha: true,
						width,
						height,
						fit: 'fill',
						poolSize: 1,
					});
					iterator = canvasSink.canvases(
						videoStartTimestamp,
						videoEndTimestamp,
					);
					let nextFrame = await iterator.next();
					if (nextFrame.done) {
						throw new Error(
							'The primary video track contains no presentable decodable frames.',
						);
					}

					throwIfAborted(options.signal);

					const baseCanvas = createVideoMattingCanvas({width, height});
					const foregroundCanvas = createVideoMattingCanvas({width, height});
					const baseContext = getVideoMattingCanvasContext(baseCanvas);
					const foregroundContext =
						getVideoMattingCanvasContext(foregroundCanvas);

					baseOutput = await createVideoLayerOutput({
						format: new WebMOutputFormat(),
						options: options.outputs?.base,
					});
					throwIfAborted(options.signal);
					foregroundOutput = await createVideoLayerOutput({

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Confirm the file plays fully in a video player; if it stalls at 0:00 the data is likely truncated — re-download or re-encode.
  2. Re-encode with ffmpeg to regenerate valid frames: ffmpeg -i broken.mp4 -c:v libx264 -crf 20 fixed.mp4.
  3. Check the source isn't DRM/encrypted (Encrypted Media Extensions content cannot be decoded by WebCodecs).
  4. If timestamps are exotic, remux to normalize timestamps before processing.

Example fix

// before
await separateVideoLayers({src: truncatedDownload});
// after
const ok = await canDecodeFirstFrame(truncatedDownload); // your probe
if (!ok) throw new Error('Source has no decodable frames');
await separateVideoLayers({src: truncatedDownload});
Defensive patterns

Strategy: validation

Validate before calling

const input = new Input({source: new BlobSource(file), formats: ALL_FORMATS});
const track = await input.getPrimaryVideoTrack();
if (!(await track.canDecode())) throw new Error('Track has no decodable frames');
// also verify file completeness (e.g. expected size/checksum) before processing

Try / catch

try {
  await separateVideoLayers({src});
} catch (e) {
  if (e instanceof Error && e.message.includes('no presentable decodable frames')) {
    const fixed = await reEncodeWithFfmpeg(src);
    return separateVideoLayers({src: fixed});
  }
  throw e;
}

Prevention

When it happens

Trigger: A video whose packets all fail to decode (corrupt keyframes, unsupported profile found only at decode time), a track whose frames all lie outside the computed start/end timestamp window, or a container advertising frames that don't exist (truncated file).

Common situations: Truncated downloads missing the media data after moov; recordings where only metadata was written; files with unusual negative/offset timestamps so the sink window contains no samples; DRM-protected tracks that fail decode silently.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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