remotion-dev/remotion · error · Error
Pass at least one subset to loadVariableFont()
Error message
Pass at least one subset to loadVariableFont()
What it means
loadVariableFont() loads a Google variable font but requires the caller to explicitly list which Unicode subsets (e.g. 'latin', 'cyrillic') to load. The library throws this error when options.subsets is an empty array, because loading zero subsets would produce no usable @font-face resources. It is a fail-fast validation of a required, non-empty option.
Solutions
- Pass at least one valid subset name in options.subsets, e.g. {subsets: ['latin']}
- Check which subsets the font actually supports via the font's metadata (meta.subsets) and include the ones you need
- If subsets are computed dynamically, validate the array is non-empty (or fall back to ['latin']) before calling
Example fix
// before
await loadVariableFont(font, {style: 'normal', subsets: []});
// after
await loadVariableFont(font, {style: 'normal', subsets: ['latin']}); Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(options.subsets) || options.subsets.length === 0) {
throw new Error('loadVariableFont() requires at least one subset, e.g. ["latin"]');
} Type guard
function hasSubsets(o: {subsets?: string[]} | null): o is {subsets: string[]} {
return !!o && Array.isArray(o.subsets) && o.subsets.length > 0;
} Try / catch
try {
await loadVariableFont(font, {style: 'normal', subsets});
} catch (e) {
if ((e as Error).message.includes('Pass at least one subset')) {
await loadVariableFont(font, {style: 'normal', subsets: ['latin']});
} else throw e;
} Prevention
- Never pass a literal empty array to subsets
- Default dynamic subset lists to ['latin'] when the computed list is empty
- Validate subsets against the font's metadata before calling
When it happens
Trigger: Calling loadVariableFont() (via loadVariableFonts) with an options object whose subsets property is [], e.g. loadVariableFont(meta, {subsets: [], style: 'normal'}), typically because subsets were built dynamically from a filter or variable that resolved to nothing.
Common situations: Deriving subsets from user config or metadata where the list ends up empty (e.g. filtering subsets that no longer exist in the current @remotion/google-fonts version); copy-pasting the function call and forgetting to fill in subsets; generating the call from code that emits an empty array literal.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- loadFont() requires a "url" field in the options object…
- loadFont() requires an object as its argument, but received
- Called measureText() with "fontFamily
- "colors" must be an array with at least 2 colors, but got
- Could not automatically derive font format from extension
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/302cc2694c2a3e9b.
Report an issue: GitHub.
Appendix: source
Thrown at packages/google-fonts/src/base.ts:263
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,
);
const subsets = [
...new Set(
options.subsets.flatMap((requestedSubset) =>
resolveFontSubsetKeys({View on GitHub (pinned to 46a3a6bf13)