remotion-dev/remotion · error · Error

src must be a string or URL when using `fetchReader`

Error message

src must be a string or URL when using `fetchReader`

What it means

Thrown by fetchCreateAdjacentFileSource when resolving an auxiliary/adjacent file path relative to a fetch-based media source. The reader constructs a URL via new URL(relativePath, src), which requires src to be a string or URL object. A Blob, File, or other non-URL src cannot be used with the fetch reader's adjacent-file mechanism. This is a type/contract guard ensuring URL resolution works.

Source

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

export const fetchReadWholeAsText: ReadWholeAsText = async (src) => {
	if (typeof src !== 'string' && src instanceof URL === false) {
		throw new Error('src must be a string when using `fetchReader`');
	}

	const res = await fetch(src);
	if (!res.ok) {
		throw new Error(`Failed to fetch ${src} (HTTP code: ${res.status})`);
	}

	return res.text();
};

export const fetchCreateAdjacentFileSource: CreateAdjacentFileSource = (
	relativePath,
	src,
) => {
	if (typeof src !== 'string' && src instanceof URL === false) {
		throw new Error('src must be a string or URL when using `fetchReader`');
	}

	return new URL(relativePath, src).toString();
};

export const fetchReader: MediaParserReaderInterface = {
	read: fetchReadContent,
	readWholeAsText: fetchReadWholeAsText,
	createAdjacentFileSource: fetchCreateAdjacentFileSource,
	preload: fetchPreload,
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure the src passed to the fetch reader is an absolute http(s) URL string (or URL object) before parseMedia runs, e.g. convert Blobs via URL.createObjectURL(blob).
  2. If you have a File/Blob, use webFileReader (or inputTypeFileReader) instead of fetchReader.
  3. Verify the reader selected by srcType matches the src type: fetchReader expects string|URL, nodeReader expects a string path, webFileReader expects a File/Blob.

Example fix

// before
await parseMedia({ src: myBlob, fields: { ... } }); // with fetch reader implied

// after
const url = URL.createObjectURL(myBlob);
await parseMedia({ src: url, fields: { ... } });
Defensive patterns

Strategy: validation

Validate before calling

function assertFetchSrc(src: unknown): asserts src is string | URL {
  if (typeof src !== 'string' && !(src instanceof URL)) {
    throw new TypeError('fetchReader requires src to be string|URL; got ' + (src as object)?.constructor?.name);
  }
}
assertFetchSrc(src);

Type guard

const isFetchSrc = (s: unknown): s is string | URL => typeof s === 'string' || s instanceof URL;

Try / catch

try { await parseMedia({ src, srcType: 'fetch', fields }); } catch (e) { if (/src must be a string or URL/.test(String((e as Error).message))) { src = URL.createObjectURL(blob); /* retry */ } else throw e; }

Prevention

When it happens

Trigger: Calling parseMedia with srcType 'fetch' (or a reader whose createAdjacentFileSource resolves to fetchCreateAdjacentFileSource) where the passed src is a Blob, File, or other non-string/non-URL value, and the parser subsequently tries to fetch an adjacent file (e.g. a sidecar .vtt, external moov atom, or companion asset referenced relative to the media).

Common situations: Swapping a File/Blob-based parseMedia call to the fetch reader without converting src to an object URL. Passing a pre-fetched Response body or Blob URL string that is not a valid URL. Mixing webFileReader expectations into a fetchReader code path.

Related errors


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