actualbudget/actual · error
Invalid font-family value for "${property}": empty font name
Error message
Invalid font-family value for "${property}": empty font name in comma-separated list. What it means
validateFontFamilyValue splits the font-family value on commas and validates each name after stripping quotes. This error is thrown when one of the comma-separated entries is empty (e.g. a trailing comma or consecutive commas), meaning the font stack names no font at that position.
Source
Thrown at packages/desktop-client/src/style/customThemes.ts:127
* 'Fira Code', monospace
* "My Theme Font", sans-serif
*/
function validateFontFamilyValue(value: string, property: string): void {
const trimmed = value.trim();
if (!trimmed) {
throw new Error(
`Invalid font-family value for "${property}": value must not be empty.`,
);
}
// Split on commas, then validate each font name
const families = trimmed.split(',');
for (const raw of families) {
const name = stripQuotes(raw);
if (!name) {
throw new Error(
`Invalid font-family value for "${property}": empty font name in comma-separated list.`,
);
}
// Reject anything that looks like a function call (url(), expression(), etc.)
if (/\(/.test(name)) {
throw new Error(
`Invalid font-family value for "${property}": function calls are not allowed. Only font names are permitted.`,
);
}
}
}
/** Only var(--custom-property-name) is allowed; no fallbacks. Variable name: -- then [a-zA-Z0-9_-]+ (no trailing dash). */
const VAR_ONLY_PATTERN = /^var\s*\(\s*(--[a-zA-Z0-9_-]+)\s*\)$/i;
function isValidSimpleVarValue(value: string): boolean {
const m = value.trim().match(VAR_ONLY_PATTERN);View on GitHub (pinned to d4334cb6e6)
Solutions
- Remove the empty entry or dangling comma in the font stack.
- Ensure every comma-separated item names a font or a generic family.
- Reinstall the theme after correcting actual.css.
Example fix
// before --font-ui: Inter, , sans-serif; // after --font-ui: Inter, sans-serif;
Defensive patterns
Strategy: validation
Validate before calling
function hasNoEmptyFontEntries(v) {
return v.split(',').every(part => part.replace(/^["']|["']$/g, '').trim() !== '');
}
if (!hasNoEmptyFontEntries(value)) throw new Error('dangling comma in font stack'); Type guard
function isWellFormedFontList(v: string): boolean {
return v.trim().split(',').every(p => p.replace(/['"]/g, '').trim() !== '');
} Try / catch
try {
await installTheme(css);
} catch (err) {
if ((err as Error).message.includes('empty font name')) {
// highlight the malformed font stack for the theme author
} else throw err;
} Prevention
- Avoid hand-editing comma-separated font stacks; use a linter that flags dangling commas.
- Test-render the font stack in a browser before publishing the theme.
- Generate font lists programmatically from a fixed array joined with ', '.
When it happens
Trigger: A --font-* variable value like `--font-ui: Inter,, sans-serif;` or `--font-mono: 'Fira Code', ;` in the theme's actual.css — any entry that is empty after quote stripping triggers the throw.
Common situations: Theme author left a dangling comma after editing the font stack; string concatenation or templating in a theme generator produced ',,'; hand-editing removed a font name but not its comma.
Related errors
- Invalid font-family value for "${property}": value must not
- Invalid font-family value for "${property}": function calls
- Invalid value "${trimmedValue}" for property "${property}".
- Theme CSS contains nested blocks or additional selectors. On
- Invalid font src: only data: URIs are allowed in @font-face.
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/554c1d682116b5d9.
Report an issue: GitHub.