remotion-dev/remotion · error · Error

Stream does not have a resolution

Error message

Stream does not have a resolution

What it means

Thrown by afterManifestFetch after a stream variant is selected from an HLS master playlist via selectStream(). The selected variant's #EXT-X-STREAM-INF line must include a RESOLUTION attribute (e.g. RESOLUTION=1920x1080). The parser stores this as M3uStream.dimensions and requires it to be non-null at after-manifest-fetch.ts:59 because downstream decoding needs a concrete video frame size to proceed.

Source

Thrown at packages/media-parser/src/containers/m3u/after-manifest-fetch.ts:60

	// 2. If streams === null: Single media playlist (has EXT-X-INDEPENDENT-SEGMENTS but no EXT-X-STREAM-INF)
	// Both cases should iterate over the current URL as the media playlist
	if (!independentSegments || streams === null) {
		if (!src) {
			throw new Error('No src');
		}

		m3uState.setSelectedMainPlaylist({
			type: 'initial-url',
			url: src,
		});

		return m3uState.setReadyToIterateOverM3u();
	}

	const selectedPlaylist = await selectStream({streams, fn: selectM3uStreamFn});

	if (!selectedPlaylist.dimensions) {
		throw new Error('Stream does not have a resolution');
	}

	m3uState.setSelectedMainPlaylist({
		type: 'selected-stream',
		stream: selectedPlaylist,
	});

	const skipAudioTracks =
		onAudioTrack === null && canSkipTracks.doFieldsNeedTracks() === false;

	const associatedPlaylists = await selectAssociatedPlaylists({
		playlists: selectedPlaylist.associatedPlaylists,
		fn: selectAssociatedPlaylistsFn,
		skipAudioTracks,
	});
	m3uState.setAssociatedPlaylists(associatedPlaylists);

	const playlistUrls = [

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Provide a custom selectM3uStream callback that filters to streams where stream.dimensions !== null before returning an id
  2. Ensure the master playlist #EXT-X-STREAM-INF lines include RESOLUTION=WxH for every video variant
  3. If the stream is genuinely audio-only, parse the audio-only media playlist directly instead of through the master-playlist path

Example fix

// before — default callback may pick a resolution-less variant
await parseMedia({src: 'https://cdn.example.com/master.m3u8'});

// after — select a variant that has dimensions
await parseMedia({
  src: 'https://cdn.example.com/master.m3u8',
  selectM3uStream: ({streams}) => {
    const withRes = streams.filter((s) => s.dimensions !== null);
    if (withRes.length === 0) throw new Error('No video variants');
    return withRes[0].id;
  },
});
Defensive patterns

Strategy: validation

Validate before calling

// Pass a custom selectM3uStream that skips resolution-less variants
await parseMedia({
  src: 'https://cdn.example.com/master.m3u8',
  selectM3uStream: ({streams}) => {
    const video = streams.filter((s) => s.dimensions !== null);
    if (video.length === 0) {
      throw new Error('No video variant with resolution found');
    }
    return video[0].id;
  },
});

Type guard

// Type guard for streams that carry resolution
const hasResolution = (s: M3uStream): s is M3uStream & {dimensions: {width: number; height: number}} =>
  s.dimensions !== null;

Try / catch

try {
  await parseMedia({src, selectM3uStream: myFn});
} catch (e) {
  if (e instanceof Error && e.message === 'Stream does not have a resolution') {
    // handle: pick a different stream or fall back
  }
  throw e;
}

Prevention

When it happens

Trigger: A master playlist where the #EXT-X-STREAM-INF line for the selected variant omits RESOLUTION (common for audio-only variants or streams from encoders that don't set it). Also fired when a custom selectM3uStream callback returns the id of a variant whose dimensions are null — for example selecting an audio-only stream or an I-frame-only variant.

Common situations: Audio-only HLS streams that have no video resolution; playlists from CDNs or encoders (FFmpeg, MediaConvert) that omit RESOLUTION on some variants; a user-provided selectM3uStream callback that picks streams[0] without checking whether dimensions exist.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/ef10203634b553fc. Report an issue: GitHub.