siyuan-note/siyuan · error
inline style [%s] must define color or backgroundColor
Error message
inline style [%s] must define color or backgroundColor
What it means
After both themes validate, the style must actually style something: at least one of Color or BackgroundColor must be non-empty in the light theme (the dark theme is checked symmetrically via the same-fields rule). A style with no colors in either field carries no visual effect and is rejected.
Source
Thrown at kernel/model/inline_style.go:693
if maxInlineStyleNameRunes < utf8.RuneCountInString(name) {
return nil, fmt.Errorf("inline style name exceeds the %d character limit", maxInlineStyleNameRunes)
}
if style.Light == nil || style.Dark == nil {
return nil, fmt.Errorf("inline style [%s] must define light and dark themes", id)
}
light, err := normalizeInlineStyleTheme(style.Light)
if err != nil {
return nil, fmt.Errorf("invalid light theme of inline style [%s]: %w", id, err)
}
dark, err := normalizeInlineStyleTheme(style.Dark)
if err != nil {
return nil, fmt.Errorf("invalid dark theme of inline style [%s]: %w", id, err)
}
lightColor, lightBackground := light.Color != "", light.BackgroundColor != ""
darkColor, darkBackground := dark.Color != "", dark.BackgroundColor != ""
if !lightColor && !lightBackground {
return nil, fmt.Errorf("inline style [%s] must define color or backgroundColor", id)
}
if lightColor != darkColor || lightBackground != darkBackground {
return nil, fmt.Errorf("inline style [%s] must use the same fields in light and dark themes", id)
}
ret = append(ret, &InlineStyle{ID: id, Name: name, Hidden: style.Hidden, Light: light, Dark: dark})
}
return ret, nil
}
func normalizeInlineStyleBuiltin(builtin *InlineStyleBuiltin) (ret *InlineStyleBuiltin, err error) {
ret = newEmptyInlineStyleBuiltin()
if builtin == nil {
return ret, nil
}
colorIndexes := make(map[int]struct{}, len(builtin.Colors))
for _, color := range builtin.Colors {View on GitHub (pinned to 8641553a1f)
Solutions
- Set at least Color or BackgroundColor (in both themes) before saving the style list.
- Drop placeholder entries that have no colors from the list.
- Fix the on-disk JSON by adding a color or removing the empty entry so loadInlineStyles succeeds.
Example fix
// before
&InlineStyle{ID: "20240101120000-abcdefg", Name: "Red",
Light: &InlineStyleTheme{}, Dark: &InlineStyleTheme{}}
// after
&InlineStyle{ID: "20240101120000-abcdefg", Name: "Red",
Light: &InlineStyleTheme{Color: "#ff0000"}, Dark: &InlineStyleTheme{Color: "#ff0000"}} Defensive patterns
Strategy: validation
Validate before calling
for (const s of styles) { const t = s.Light; if (!t.Color && !t.BackgroundColor) throw new Error(`style ${s.ID} has no color or backgroundColor`); } Type guard
const hasVisualEffect = (t: InlineStyleTheme): boolean => t.Color !== '' || t.BackgroundColor !== '';
Try / catch
try { await saveStyles(styles) } catch (e) { if (/must define color or backgroundColor/.test(String(e))) { /* remove the empty style or set a color, then retry */ } } Prevention
- Do not save placeholder styles with empty themes — delete them instead
- Require at least one color in the style-creation UI
- Validate the full list before bulk saves
When it happens
Trigger: setInlineStylesData receives an InlineStyle whose Light theme has both Color and BackgroundColor empty (dark likewise); loadInlineStyles reads a JSON entry with both color fields empty or absent in both themes.
Common situations: Creating a style entry reserved for later and saving before filling colors; a UI flow that clears both color pickers; migration tools copying style shells without theme payloads.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- inline style name must not be empty
- Tag cannot be empty
- block write failed: empty block ID
- Conf.Language(126) (localized empty-bookmark-name message)
- invalid color [%s]
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/ec6f6466e6fecea9.
Report an issue: GitHub.