remotion-dev/remotion · error · Error

Expected an array of associated playlists

Error message

Expected an array of associated playlists

What it means

Thrown by `selectAssociatedPlaylists` when the user-supplied `selectM3uAssociatedPlaylists` callback returns a value that is not an array. The callback contract (`SelectM3uAssociatedPlaylistsFn`) requires returning `M3uAssociatedPlaylist[]`; returning `undefined`, `null`, an object, or a single non-array value triggers this guard.

Source

Thrown at packages/media-parser/src/containers/m3u/select-stream.ts:34

	options: SelectM3uAssociatedPlaylistsFnOptions,
) => M3uAssociatedPlaylist[] | Promise<M3uAssociatedPlaylist[]>;

export const selectAssociatedPlaylists = async ({
	playlists,
	fn,
	skipAudioTracks,
}: {
	playlists: M3uAssociatedPlaylist[];
	fn: SelectM3uAssociatedPlaylistsFn;
	skipAudioTracks: boolean;
}): Promise<M3uAssociatedPlaylist[]> => {
	if (playlists.length < 1) {
		return Promise.resolve([]);
	}

	const streams = await fn({associatedPlaylists: playlists});
	if (!Array.isArray(streams)) {
		throw new Error('Expected an array of associated playlists');
	}

	const selectedStreams: M3uAssociatedPlaylist[] = [];
	for (const stream of streams) {
		if (stream.isAudio && skipAudioTracks) {
			continue;
		}

		if (!playlists.find((playlist) => playlist.src === stream.src)) {
			throw new Error(
				`The associated playlist ${JSON.stringify(streams)} cannot be selected because it was not in the list of selectable playlists`,
			);
		}

		selectedStreams.push(stream);
	}

	return selectedStreams;

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure your `selectM3uAssociatedPlaylists` callback always returns an array, even for a single selection.
  2. Use `Array.isArray()` on the return value before returning it, or spread a single result: `return [playlist]`.
  3. Use the default `defaultSelectM3uAssociatedPlaylists` if you don't need custom logic.
  4. Type-check the callback against `SelectM3uAssociatedPlaylistsFn` to let TypeScript catch this at compile time.

Example fix

// before
selectM3uAssociatedPlaylists: ({associatedPlaylists}) => {
  return associatedPlaylists.find(p => p.default); // returns object, not array
}

// after
selectM3uAssociatedPlaylists: ({associatedPlaylists}) => {
  return associatedPlaylists.filter(p => p.default); // returns array
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Wrap your callback to guarantee array return
import {
  defaultSelectM3uAssociatedPlaylists,
  type SelectM3uAssociatedPlaylistsFn,
} from '@remotion/media-parser';

const safeSelect: SelectM3uAssociatedPlaylistsFn = async (opts) => {
  const result = await myCustomSelect(opts);
  if (!Array.isArray(result)) {
    throw new TypeError('selectM3uAssociatedPlaylists must return an array');
  }
  return result;
};

Type guard

import type {M3uAssociatedPlaylist} from '@remotion/media-parser';

function isPlaylistArray(value: unknown): value is M3uAssociatedPlaylist[] {
  return Array.isArray(value) && value.every(
    (v) => v !== null && typeof v === 'object' && 'src' in v
  );
}

Try / catch

try {
  await parseMedia({src, selectM3uAssociatedPlaylists: myFn});
} catch (e) {
  if (e instanceof Error && e.message === 'Expected an array of associated playlists') {
    console.error('Your selectM3uAssociatedPlaylists callback must return an array.');
  }
  throw e;
}

Prevention

When it happens

Trigger: Providing a custom `selectM3uAssociatedPlaylists` option to `parseMedia()` that returns `null`, `undefined`, a single playlist object, or any non-array value from the callback function.

Common situations: A custom callback that forgets to wrap a single selection in an array. A callback that returns the result of `.find()` (single element) instead of `.filter()` (array). A callback that conditionally returns `undefined` on some branch.

Related errors


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