withastro/astro · error · AstroError

FontFileUrlNotFound

FontFileUrlNotFound

Error message

The `"${url}"` URL passed to the `experimental_getFontFileURL()` function is invalid.

What it means

experimental_getFontFileURL() asks the runtime font URL resolver to resolve the given URL; if the resolver returns null (the URL is not in the known set of generated font file URLs) or throws, the failure is wrapped as AstroError FontFileUrlNotFound. Only URLs obtained from the fontData object are valid inputs.

Source

Thrown at packages/astro/src/assets/fonts/core/create-get-font-file-url.ts:13

import { AstroError, AstroErrorData } from '../../../core/errors/index.js';
import type { RuntimeFontFileUrlResolver } from '../definitions.js';

export function createGetFontFileURL(runtimeFontFileUrlResolver: RuntimeFontFileUrlResolver) {
	return function getFontFileURL(url: string, requestUrl?: URL): string {
		try {
			const result = runtimeFontFileUrlResolver.resolve(url, requestUrl);
			if (result === null) {
				throw new Error('Not found');
			}
			return result;
		} catch (cause) {
			throw new AstroError(
				{
					...AstroErrorData.FontFileUrlNotFound,
					message: AstroErrorData.FontFileUrlNotFound.message(url),
				},
				{ cause },
			);
		}
	};
}

View on GitHub (pinned to d081033d5f)

Solutions

  1. Pass only URLs that come from the fontData object returned by the fonts API.
  2. For on-demand rendering, pass the request URL as the second argument: getFontFileURL(url, Astro.url).
  3. Rebuild after changing fonts so the resolver's known URL set is up to date.

Example fix

// before
const url = experimental_getFontFileURL('/fonts/roboto.woff2');
// after - use the URL from fontData, and pass Astro.url in SSR
const url = experimental_getFontFileURL(fontData.fonts[0].url, Astro.url);
Defensive patterns

Strategy: validation

Validate before calling

// Only pass URLs that belong to the fontData set, and always supply Astro.url in SSR.
const known = new Set(fontData.fonts.map((f) => f.url));
if (!known.has(url)) throw new Error(`Unknown font URL "${url}". Use a URL from fontData.`);
const resolved = experimental_getFontFileURL(url, Astro.url);

Type guard

function isKnownFontUrl(fontData: { fonts: Array<{ url: string }> }, url: string): boolean {
  return fontData.fonts.some((f) => f.url === url);
}

Try / catch

try {
  const u = experimental_getFontFileURL(url, Astro.url);
} catch (e) {
  if (e instanceof AstroError && e.name === 'FontFileUrlNotFound') {
    // pick a valid URL from fontData and rebuild if fonts changed
  } else throw e;
}

Prevention

When it happens

Trigger: Passing an arbitrary/hardcoded string to getFontFileURL() instead of a value from fontData; passing a URL after the font set changed (stale build); on-demand SSR where a slash-prefixed URL needs requestUrl but none was supplied.

Common situations: Hardcoding a font file URL; reusing a URL from a previous build after fonts changed; SSR calling getFontFileURL(url) without the second Astro.url argument.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/f79bea38927df72a. Report an issue: GitHub.