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
- 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.
- If you have the manifest text but no URL, host it so it has a resolvable base URL and pass that URL as `src`.
- If you must parse from a buffer, convert MP4/WebM files directly instead of wrapping them in an M3U8 container.
- 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
- Always pass HLS/M3U8 sources as URL strings to parseMedia.
- Do not pass ArrayBuffer, Blob, or File objects as src for M3U8 playlists.
- For non-URL MP4/WebM sources, use buffer-based parsing instead of HLS.
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
- Expected m3u-playlist with src ${src}
- No moov box found in header segment
- Stream does not have a resolution
- Expected m3u-text-value
- Expected duration in m3u playlist
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/44d71b56d7c0b1d4.
Report an issue: GitHub.