remotion-dev/remotion · error · TypeError

loadFont() requires a "url" field in the options object, but

Error message

loadFont() requires a "url" field in the options object, but received ${url === undefined ? 'undefined' : JSON.stringify(url)}. If you want to load a Google Font, use the @remotion/google-fonts package instead. See: https://www.remotion.dev/docs/google-fonts/load-font

What it means

The `loadFont` function validates that the options object contains a `url` field of type string after the initial object-type check. If `url` is undefined, null, a number, or any non-string, it throws a TypeError showing the received value (via `JSON.stringify`). This runs before any font loading begins and before `delayRender` is called.

Source

Thrown at packages/fonts/src/load-font.ts:45

	const {
		family,
		url,
		ascentOverride,
		descentOverride,
		display,
		featureSettings,
		lineGapOverride,
		stretch,
		style,
		unicodeRange,
		weight,
		format,
		variant,
	} = options;

	if (typeof url !== 'string') {
		throw new TypeError(
			`loadFont() requires a "url" field in the options object, but received ${url === undefined ? 'undefined' : JSON.stringify(url)}. If you want to load a Google Font, use the @remotion/google-fonts package instead. See: https://www.remotion.dev/docs/google-fonts/load-font`,
		);
	}

	const waitForFont = delayRender(
		`Loading font ${family} (url: ${url}, format: ${format}, weight: ${weight}, style: ${style}, variant: ${variant}, ascentOverride: ${ascentOverride}, descentOverride: ${descentOverride}, display: ${display}, featureSettings: ${featureSettings}, lineGapOverride: ${lineGapOverride}, stretch: ${stretch}, unicodeRange: ${unicodeRange})`,
	);
	try {
		const fontFormat = format ?? getFontFormat(url);
		const font = new FontFace(family, `url('${url}') format('${fontFormat}')`, {
			ascentOverride,
			descentOverride,
			display,
			featureSettings,
			lineGapOverride,
			stretch,
			style,
			unicodeRange,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Add a `url` string field to the options object.
  2. Check the spelling of the `url` key (it must be exactly `url`).
  3. If building the options dynamically, validate the URL is set before calling `loadFont`.

Example fix

// before
loadFont({ family: 'MyFont' });

// after
loadFont({ family: 'MyFont', url: '/fonts/myfont.woff2' });
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof options.url !== 'string' || options.url.length === 0) {
  throw new TypeError('loadFont requires a string url field');
}
loadFont(options);

Type guard

const hasUrlString = (v: unknown): v is { url: string } =>
  typeof v === 'object' &&
  v !== null &&
  'url' in v &&
  typeof (v as { url: unknown }).url === 'string';

Prevention

When it happens

Trigger: Calling `loadFont({family: 'MyFont'})` (no `url`), `loadFont({family: 'MyFont', url: 123})`, or `loadFont({family: 'MyFont', url: null})`. Also triggered by a destructuring mistake that drops the `url` key.

Common situations: Misspelling the `url` key (e.g., `src` or `href`), building the options object dynamically and forgetting to set `url`, or passing a font config from external data where the URL field is absent.

Related errors


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