remotion-dev/remotion · error · Error

src must be a string when using `fetchReader`

Error message

src must be a string when using `fetchReader`

What it means

fetchReadContent (the reader's `read` entry) validates that src is a string or URL before proceeding; otherwise it throws. The fetch reader can only fetch over HTTP(S)/blob/data, so non-string/URL sources (e.g. a File, a Buffer, or a filesystem path) are rejected. This is the default reader when none is provided in the browser.

Source

Thrown at packages/media-parser/src/readers/from-fetch.ts:244

		Log.verbose(logLevel, `Reading from preload cache for ${key}`);
		return cached;
	}

	Log.verbose(logLevel, `Fetching ${key}`);
	const result = makeFetchRequest({range, src, controller});
	prefetchCache.set(key, result);
	return result;
};

export const fetchReadContent: ReadContent = async ({
	src,
	range,
	controller,
	logLevel,
	prefetchCache,
}) => {
	if (typeof src !== 'string' && src instanceof URL === false) {
		throw new Error('src must be a string when using `fetchReader`');
	}

	const fallbackName = src.toString().split('/').pop() as string;

	const res = makeFetchRequestOrGetCached({
		range,
		src,
		controller,
		logLevel,
		prefetchCache,
	});

	const key = cacheKey({src, range});
	prefetchCache.delete(key);

	const {
		reader,
		contentLength,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. For browser File/Blob, create an object URL first: `URL.createObjectURL(file)` and pass that string as src.
  2. For Node filesystem paths, pass `reader: nodeReader` (from @remotion/media-parser/node-reader).
  3. Ensure src is `string | URL` when using the default fetchReader.
  4. Double-check you imported and set the reader if your src is not HTTP-addressable.

Example fix

// before (browser File with default reader)
await parseMedia({src: userFile, fields: {durationInSeconds: true}}); // File

// after
const url = URL.createObjectURL(userFile);
await parseMedia({src: url, fields: {durationInSeconds: true}});
URL.revokeObjectURL(url);

// (Node filesystem)
import {nodeReader} from '@remotion/media-parser/node-reader';
await parseMedia({src: '/data/video.mp4', reader: nodeReader, fields: {}});
Defensive patterns

Strategy: type-guard

Validate before calling

// Normalize src before parse: object URL for File, nodeReader for FS
function normalizeSrc(src: unknown, inNode: boolean) {
  if (src instanceof File || src instanceof Blob) return URL.createObjectURL(src);
  if (typeof src === 'string' || src instanceof URL) return src;
  throw new Error('src must be string | URL | File');
}

Type guard

const isFetchableSrc = (src: unknown): src is string | URL =>
  typeof src === 'string' || src instanceof URL;

Try / catch

try {
  await parseMedia({src, fields: {durationInSeconds: true}});
} catch (e) {
  if (e instanceof Error && e.message === 'src must be a string when using `fetchReader`') {
    // src was a File/path: convert or switch reader
    throw new Error('Pass an object URL (browser) or reader: nodeReader (node)');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling parseMedia without specifying reader, while passing a File, Blob, ArrayBuffer, or a raw filesystem path as src — i.e. relying on the default fetchReader for something it cannot fetch.

Common situations: Browser code passing a `File` from an <input type=file> but forgetting that fetchReader expects a URL; Node code passing a local path without setting `reader: nodeReader`; passing a Buffer/ReadableStream as src.

Related errors


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