remotion-dev/remotion · warning · Error
Called measureText() with "fontFamily": ${JSON.stringify(fon
Error message
Called measureText() with "fontFamily": ${JSON.stringify(fontFamily)} but it looks like the font is not loaded at the time of calling.
A measurement with the fallback font ${computedFallback} was taken and had the same dimensions, indicating that the browser used the fallback font.
See https://remotion.dev/docs/layout-utils/best-practices for best practices. What it means
When measureText() is called with validateFontIsLoaded: true, it measures the text twice (with the requested fontFamily and with no family / fallback). If both measurements match exactly, the requested font and the fallback differ in the computed style, and the text has at least 5 unique characters, the library concludes the requested font was never actually loaded and the browser silently substituted the fallback — a common cause of layout drift. It throws to force you to await font load.
Source
Thrown at packages/layout-utils/src/layouts/measure-text.ts:178
const sameAsFallbackFont =
boundingBox.height === boundingBoxOfFallbackFont.height &&
boundingBox.width === boundingBoxOfFallbackFont.width;
// Ensure there are at least 4 unique characters, with just a few, there is more likely to be a false positive
if (
sameAsFallbackFont &&
computedFallback !== computedFontFamily &&
new Set(text).size > 4
) {
const err = [
`Called measureText() with "fontFamily": ${JSON.stringify(
fontFamily,
)} but it looks like the font is not loaded at the time of calling.`,
`A measurement with the fallback font ${computedFallback} was taken and had the same dimensions, indicating that the browser used the fallback font.`,
'See https://remotion.dev/docs/layout-utils/best-practices for best practices.',
];
throw new Error(err.join('\n'));
}
}
const result = {height: boundingBox.height, width: boundingBox.width};
wordCache.set(key, result);
return result;
};
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Load the font via @remotion/fonts (staticFile + <Font>) or @remotion/google-fonts and wait for its load promise before measuring.
- Use delayRender/continueRender to gate the component until `document.fonts.ready` or the font's onLoad fires.
- Verify the fontFamily string exactly matches the font's CSS family name (case- and space-sensitive).
- If you must measure early, pass validateFontIsLoaded:false and accept fallback-tolerance.
Example fix
// before
const dims = measureText({text: title, fontFamily: 'Inter', fontSize: 24, validateFontIsLoaded: true});
// after
const handle = delayRender('load Inter');
useEffect(() => {
document.fonts.load('700 24px Inter').then(() => continueRender(handle));
}, []); Defensive patterns
Strategy: validation
Validate before calling
const fontReady = await document.fonts.load(`${fontWeight ?? 400} ${fontSize}px ${fontFamily}`);
// only measure after this resolves Type guard
export const isFontLoaded = async (family: string): Promise<boolean> => {
try { await document.fonts.load(`16px "${family}"`); return true; }
catch { return false; }
}; Try / catch
try {
const dims = measureText({text, fontFamily, fontSize, validateFontIsLoaded: true});
} catch (e) {
if (/font is not loaded/i.test((e as Error).message)) {
await document.fonts.ready; // then retry
} else throw e;
} Prevention
- Load fonts with @remotion/fonts or @remotion/google-fonts and await their load promise.
- Gate the measuring component with delayRender until document.fonts.ready.
- Use the exact CSS family name (case- and space-sensitive).
- Avoid passing validateFontIsLoaded:true on the very first frame if fonts are still loading.
When it happens
Trigger: Calling measureText() with validateFontIsLoaded:true before @remotion/google-fonts / @remotion/fonts / a <Font> load has resolved; using a fontFamily name that does not match the loaded font's CSS family name; rendering on a frame where the font fetch is still in flight.
Common situations: Forgetting to delayRender until fonts load; referencing a font by file name instead of its CSS family name; mixing @remotion/google-fonts with a manual <link> that races; measureText being called synchronously during the first frame before the FontFace is ready.
Related errors
- Expected a URL string but received ${url === undefined ? 'un
- loadFont() requires an object as its argument, but received
- loadFont() requires a "url" field in the options object, but
- measureText() can only be called in a browser.
- inputRange must contain only numbers
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/9ccb6aa0a9019ab0.
Report an issue: GitHub.