remotion-dev/remotion · error · Error

Expected src to be a string

Error message

Expected src to be a string

What it means

Thrown when an HLS/M3U8 manifest has been fully parsed but the parser's internal `state.src` is neither a `string` nor a `URL` object. The parser needs a resolvable URL to fetch subsequent playlist segments, and a non-URL src (like a `File`, `Blob`, `ArrayBuffer`, or `Uint8Array`) makes segment resolution impossible.

Source

Thrown at packages/media-parser/src/containers/m3u/parse-m3u.ts:26

	if (state.m3u.isReadyToIterateOverM3u()) {
		const selectedPlaylists = state.m3u.getSelectedPlaylists();

		const whichPlaylistToRunOver =
			state.m3u.sampleSorter.getNextStreamToRun(selectedPlaylists);

		await runOverM3u({
			state,
			structure,
			playlistUrl: whichPlaylistToRunOver,
			logLevel: state.logLevel,
		});

		return null;
	}

	if (state.m3u.hasFinishedManifest()) {
		if (typeof state.src !== 'string' && !(state.src instanceof URL)) {
			throw new Error('Expected src to be a string');
		}

		state.mediaSection.addMediaSection({
			start: 0,
			// We do a pseudo-seek when seeking m3u, which will be the same byte
			// as we are currently in, which in most cases is the end of the file.
			size: state.contentLength + 1,
		});

		await afterManifestFetch({
			structure,
			m3uState: state.m3u,
			src: state.src.toString(),
			selectM3uStreamFn: state.selectM3uStreamFn,
			logLevel: state.logLevel,
			selectAssociatedPlaylistsFn: state.selectM3uAssociatedPlaylistsFn,
			readerInterface: state.readerInterface,
			onAudioTrack: state.onAudioTrack,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass the HLS playlist as a URL string (e.g., `parseMedia({src: 'https://example.com/stream.m3u8'})`) so the parser can resolve and fetch segments.
  2. If you have the manifest text but no URL, host it so it has a resolvable base URL and pass that URL as `src`.
  3. If you must parse from a buffer, convert MP4/WebM files directly instead of wrapping them in an M3U8 container.
  4. Verify `typeof src === 'string' || src instanceof URL` before calling `parseMedia` for HLS sources.

Example fix

// before
const res = await fetch('https://example.com/stream.m3u8');
const buf = await res.arrayBuffer();
await parseMedia({src: buf}); // throws for m3u8

// after
await parseMedia({src: 'https://example.com/stream.m3u8'});
Defensive patterns

Strategy: validation

Validate before calling

// Before calling parseMedia with an HLS source
import {parseMedia} from '@remotion/media-parser';

const src = options.src;
if (src instanceof URL || typeof src === 'string') {
  // Safe for M3U8 - has a resolvable URL
  await parseMedia({src, fields: {durationInSeconds: true}});
} else {
  throw new Error(
    'HLS/M3U8 sources require a string or URL src. ' +
    'Buffers, Blobs, and Files are not supported for M3U8.'
  );
}

Type guard

// Type guard for M3U-compatible src values
function isUrlSrc(src: unknown): src is string | URL {
  return typeof src === 'string' || src instanceof URL;
}

Try / catch

try {
  await parseMedia({src, fields: {durationInSeconds: true}});
} catch (e) {
  if (e instanceof Error && e.message === 'Expected src to be a string') {
    console.error('HLS sources require a URL string src, not a buffer or file.');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `parseMedia()` (or `downloadAndParseMedia()`) with an `m3u8`/HLS stream where the `src` option is a `File`, `Blob`, `ArrayBuffer`, `Uint8Array`, `ReadableStream`, or any non-string/non-URL value, and the manifest finishes loading so the parser reaches the `hasFinishedManifest()` branch in parse-m3u.ts:24-27.

Common situations: Passing a locally-read `.m3u8` file blob or `ArrayBuffer` fetched via `fetch().arrayBuffer()` directly into `parseMedia({src})` instead of passing the remote URL string. Trying to parse a downloaded master playlist that references relative segment URLs without a base URL.

Related errors


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