remotion-dev/remotion · error · Error

The input does not contain a video track.

Error message

The input does not contain a video track.

What it means

The input was readable as a media container, but mediabunny's input.getPrimaryVideoTrack() returned null, meaning the container has no video track. Video layer separation requires video frames, so the library throws. This typically means the source is audio-only or the video track is in a separate stream.

Source

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

			: new BlobSource(src);

	return new Input({formats: ALL_FORMATS, source});
};

const probeVideoInput = async ({
	input,
	videoQuality,
}: {
	input: Input;
	videoQuality: Quality;
}): Promise<{videoTrack: InputVideoTrack; width: number; height: number}> => {
	if (!(await input.canRead())) {
		throw new Error('The input is not a supported media file.');
	}

	const videoTrack = await input.getPrimaryVideoTrack();
	if (videoTrack === null) {
		throw new Error('The input does not contain a video track.');
	}

	if (!(await videoTrack.canDecode())) {
		throw new Error('The primary video track cannot be decoded.');
	}

	const [width, height] = await Promise.all([
		videoTrack.getDisplayWidth(),
		videoTrack.getDisplayHeight(),
	]);
	if (
		!Number.isInteger(width) ||
		width <= 0 ||
		!Number.isInteger(height) ||
		height <= 0
	) {
		throw new Error('The input video has invalid dimensions.');
	}

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Check the file actually contains a video stream (e.g. `ffprobe <file>` shows a video: stream).
  2. Point src at the video file, not the extracted audio file.
  3. If the video track is genuinely missing, re-mux/re-encode the source to include video before calling.

Example fix

// before
await separateVideoLayers({src: 'podcast-episode.m4a'});
// after
if (await hasVideoTrack('episode.mp4')) {
  await separateVideoLayers({src: 'episode.mp4'});
}
Defensive patterns

Strategy: validation

Validate before calling

const input = new Input({source: new BlobSource(file), formats: ALL_FORMATS});
const track = await input.getPrimaryVideoTrack();
if (!track) throw new Error('File has no video track — pick a video file');

Try / catch

try {
  await separateVideoLayers({src});
} catch (e) {
  if (e instanceof Error && e.message.includes('no video track')) {
    showUserError('This file is audio-only. Select a file with video.');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling separateVideoLayers on an MP3/M4A audio file, an audio-only WebM/MP4, or a media file whose video track was stripped during transcoding.

Common situations: Processing podcast/audio exports by mistake; a transcode pipeline that dropped video; HLS/DASH setups where only the audio segment was handed to the API.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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