remotion-dev/remotion · error · Error

src must be a string when using `nodeReader`

Error message

src must be a string when using `nodeReader`

What it means

Thrown by nodeReadContent when the src passed to the Node.js filesystem reader is not a string. The Node reader uses fs.createReadStream and fs.existsSync, both of which require a filesystem path string. URL objects, Blobs, or File instances are not supported by nodeReader.

Source

Thrown at packages/media-parser/src/readers/from-node.ts:16

import {createReadStream, existsSync, promises, statSync} from 'fs';
import {dirname, join, relative, sep} from 'path';
import type {
	CreateAdjacentFileSource,
	MediaParserReaderInterface,
	ReadContent,
	ReadWholeAsText,
} from './reader';

export const nodeReadContent: ReadContent = async ({
	src,
	range,
	controller,
}) => {
	if (typeof src !== 'string') {
		throw new Error('src must be a string when using `nodeReader`');
	}

	await Promise.resolve();

	const ownController = new AbortController();

	try {
		if (!existsSync(src)) {
			throw new Error(`File does not exist: ${src}`);
		}

		const stream = createReadStream(src, {
			start: range === null ? 0 : typeof range === 'number' ? range : range[0],
			end:
				range === null
					? Infinity
					: typeof range === 'number'
						? Infinity

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass a filesystem path string to nodeReader, e.g. '/abs/path/media.mp4' or a relative path resolved from process.cwd().
  2. If you have a URL, convert it first: for file:// URLs use url.fileURLToPath(url); for http URLs switch to fetchReader.
  3. If you have a Blob/File in Node, write it to a temp file and pass the path, or use a reader that accepts streams.

Example fix

// before
await parseMedia({ src: new URL('file:///tmp/a.mp4'), fields: {...} }); // node reader

// after
import { fileURLToPath } from 'node:url';
await parseMedia({ src: fileURLToPath('file:///tmp/a.mp4'), fields: {...} });
Defensive patterns

Strategy: validation

Validate before calling

function assertNodePath(src: unknown): asserts src is string {
  if (typeof src !== 'string') throw new TypeError('nodeReader requires a filesystem path string');
}
assertNodePath(src);

Type guard

const isNodePath = (s: unknown): s is string => typeof s === 'string' && !s.startsWith('http');

Try / catch

try { await parseMedia({ src, srcType: 'node', fields }); } catch (e) { if (/src must be a string when using `nodeReader`/.test(String((e as Error).message))) { src = fileURLToPath(src); /* retry */ } else throw e; }

Prevention

When it happens

Trigger: Calling parseMedia with srcType 'node' (or nodeReader explicitly) while passing a URL object, Blob, or File as src instead of a filesystem path string. This trips before any filesystem access is attempted.

Common situations: Sharing a src value between a browser (URL/File) and a Node SSR/render context without normalizing it. Receiving a file:// URL object from another API and passing it straight to the Node reader. Accidentally selecting nodeReader in an Electron/browser environment.

Related errors


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