remotion-dev/remotion · error · Error
is not available as a variable font
Error message
${meta.fontFamily} is not available as a variable font What it means
loadVariableFonts() (exported from @remotion/google-fonts) loads variable font axes, but only works for fonts whose metadata marks them as variable (`meta.variable` present). For static-only families the variable info does not exist, so calling this function throws `${fontFamily} is not available as a variable font`.
Solutions
- Use `loadFont()` instead of `loadVariableFonts()` for families without a variable version — it loads static weights per style/weight
- Pick a family that actually ships a variable font on Google Fonts (check the family page for an "axes" panel)
- Verify the meta object belongs to the intended family (it comes from the same family's import, e.g. `import {getInfo} from "@remotion/google-fonts/Inter"`)
- If the family does have a variable font on Google Fonts, update @remotion/google-fonts to a version whose generated metadata includes it
Example fix
// before
import {loadVariableFonts, getInfo} from "@remotion/google-fonts/Roboto";
loadVariableFonts(getInfo(), "normal", {subsets: ["latin"]}); // static-only family
// after
import {loadFont} from "@remotion/google-fonts/Roboto";
const {fontFamily, waitUntilDone} = loadFont("normal", {weights: ["400", "700"]}); Defensive patterns
Strategy: try-catch
Validate before calling
import {getInfo} from "@remotion/google-fonts/Inter";
const meta = getInfo();
if (!meta.variable) {
// fall back to loadFont() for static weights
}
Type guard
const supportsVariable = (
meta: ReturnType<typeof getInfo>,
): meta is typeof meta & {variable: NonNullable<typeof meta.variable>} =>
Boolean(meta.variable); Try / catch
try {
const vf = loadVariableFonts(meta, style, {subsets: ['latin'], ...options});
} catch (e) {
if (e.message.includes('is not available as a variable font')) {
// fall back to loadFont(meta.fontFamily === undefined ? style : style, ...)
return loadFont(style as any, options);
}
throw e;
} Prevention
- Check `getInfo().variable` before calling loadVariableFonts()
- Use loadFont() by default; only switch to loadVariableFonts() for variable-capable families
- Import meta and loader from the same family module to avoid mismatched objects
- Keep @remotion/google-fonts updated so newly variable fonts have metadata
When it happens
Trigger: Calling loadVariableFonts(fontInfo, style, {subsets: [...]}) with a FontInfo meta object for a family that has no variable version — e.g. fonts like "Arial"-style static families, or families where the package only ships static weights. Also happens when passing meta from the wrong family (copy-paste between imports).
Common situations: Migrating code from loadFont() to loadVariableFonts() without checking that the chosen family offers a variable font on Google Fonts, using an older package version where the family had no variable metadata, or destructuring meta from one import and passing it to another family's loader.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- bundle() no longer supports the legacy positional…
- bundle() was called without arguments
- bundle() was called without the `entryPoint` option
- "colors" must be an array with at least 2 colors, but got
- create-video is a CLI tool only. Run `npx…
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/6b5d9739cf9d1d36.
Report an issue: GitHub.
Appendix: source
Thrown at packages/google-fonts/src/base.ts:259
return {
fontFamily: meta.fontFamily,
fonts: meta.fonts,
unicodeRanges: meta.unicodeRanges,
waitUntilDone: () => Promise.all<void>(promises).then(() => undefined),
};
};
export const loadVariableFonts = (
meta: FontInfo,
style: string,
options: FontLoadOptions & {subsets: string[]},
): {
fontFamily: FontInfo['fontFamily'];
axes: Record<string, {min: number; max: number}>;
waitUntilDone: () => Promise<undefined>;
} => {
if (!meta.variable) {
throw new Error(`${meta.fontFamily} is not available as a variable font`);
}
if (options.subsets.length === 0) {
throw new Error('Pass at least one subset to loadVariableFont()');
}
const fontFacesForStyle = meta.variable.fontFaces.filter(
(fontFace) => fontFace.style === style,
);
if (fontFacesForStyle.length === 0) {
throw new Error(
`The variable font ${meta.fontFamily} does not have a style ${style}`,
);
}
const availableSubsetKeys = fontFacesForStyle.map(
(fontFace) => fontFace.subset,
);View on GitHub (pinned to 46a3a6bf13)