{"record":{"id":"cc973f8c56237dfd","repo":"remotion-dev/remotion","slug":"could-not-automatically-derive-font-format-from-ex","errorCode":null,"errorMessage":"Could not automatically derive font format from extension: ${ext}. Pass the \"format\" parameter explicitly.","messagePattern":"Could not automatically derive font format from extension: (.+?)\\. Pass the \"format\" parameter explicitly\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/fonts/src/get-font-format.ts","lineNumber":21,"sourceCode":"export const getFontFormat = (url: string): FontFormat => {\n\tif (typeof url !== 'string') {\n\t\tthrow new TypeError(\n\t\t\t`Expected a URL string but received ${url === undefined ? 'undefined' : typeof url}. Make sure to pass a \"url\" field in the options object of loadFont().`,\n\t\t);\n\t}\n\n\tconst ext = url.split('.').pop()?.toLowerCase();\n\tswitch (ext) {\n\t\tcase 'woff2':\n\t\t\treturn 'woff2';\n\t\tcase 'woff':\n\t\t\treturn 'woff';\n\t\tcase 'otf':\n\t\t\treturn 'opentype';\n\t\tcase 'ttf':\n\t\t\treturn 'truetype';\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`Could not automatically derive font format from extension: ${ext}. Pass the \"format\" parameter explicitly.`,\n\t\t\t);\n\t}\n};\n","sourceCodeStart":3,"sourceCodeEnd":26,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/fonts/src/get-font-format.ts#L3-L26","documentation":"The `getFontFormat` helper maps file extensions to CSS font formats: `.woff2` → `woff2`, `.woff` → `woff`, `.otf` → `opentype`, `.ttf` → `truetype`. If the URL's extension is none of these (e.g., `.eot`, `.svg`, or a URL with query parameters that obscure the extension), the function throws this error and asks you to pass `format` explicitly.","triggerScenarios":"Passing a URL ending in `.eot`, `.svg`, or no extension; passing a URL with a query string like `font.woff2?v=2` is fine (extension is still `woff2`), but a URL like `https://cdn.example.com/font?id=123` (no extension) triggers it.","commonSituations":"Using a CDN or font-hosting service that serves fonts from dynamic URLs without file extensions, loading `.eot` fonts (legacy IE), or URLs where the extension is not the last path segment.","solutions":["Pass the `format` option explicitly in `loadFont`: `format: 'woff2'`.","Use a URL that ends in a recognized extension (`.woff2`, `.woff`, `.otf`, `.ttf`).","For Google Fonts, use `@remotion/google-fonts` instead of manual `loadFont`."],"exampleFix":"// before\nloadFont({ family: 'MyFont', url: 'https://cdn.example.com/font?id=123' });\n\n// after\nloadFont({\n  family: 'MyFont',\n  url: 'https://cdn.example.com/font?id=123',\n  format: 'woff2',\n});","handlingStrategy":"validation","validationCode":"const KNOWN_EXTS = ['woff2', 'woff', 'otf', 'ttf'];\nconst ext = url.split('.').pop()?.toLowerCase();\nif (!ext || !KNOWN_EXTS.includes(ext)) {\n  // pass format explicitly\n  loadFont({ family, url, format: 'woff2' });\n} else {\n  loadFont({ family, url });\n}","typeGuard":null,"tryCatchPattern":"try {\n  loadFont({ family, url });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('derive font format')) {\n    loadFont({ family, url, format: 'woff2' }); // retry with explicit format\n  } else {\n    throw err;\n  }\n}","preventionTips":["Pass the format option explicitly when using CDN URLs without clear extensions.","Use URLs ending in .woff2, .woff, .otf, or .ttf.","For Google Fonts, use @remotion/google-fonts instead."],"tags":["fonts","validation","load-font","file-extension"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}