siyuan-note/siyuan · error
builtin style must not be null
Error message
builtin style must not be null
What it means
A null entry was found in the builtin `styles` array. Builtin styles are the fixed set (error, warning, info, success); each entry must be a non-null object so its ID and light/dark themes can be validated. A null element cannot be normalized and aborts the whole builtin configuration load.
Source
Thrown at kernel/model/inline_style.go:737
if _, exists := colorIndexes[color.Index]; exists {
return nil, fmt.Errorf("duplicate builtin color index [%d]", color.Index)
}
colorIndexes[color.Index] = struct{}{}
light, dark, err := normalizeInlineStyleThemePair(color.Light, color.Dark, fmt.Sprintf("builtin color [%d]", color.Index))
if err != nil {
return nil, err
}
ret.Colors = append(ret.Colors, &InlineStyleBuiltinColor{Index: color.Index, Light: light, Dark: dark})
}
sort.Slice(ret.Colors, func(i, j int) bool {
return ret.Colors[i].Index < ret.Colors[j].Index
})
styleIDs := make(map[string]struct{}, len(builtin.Styles))
for _, style := range builtin.Styles {
if style == nil {
return nil, errors.New("builtin style must not be null")
}
id := strings.TrimSpace(style.ID)
if _, valid := builtinStyleOrder[id]; !valid {
return nil, fmt.Errorf("invalid builtin style ID [%s]", id)
}
if _, exists := styleIDs[id]; exists {
return nil, fmt.Errorf("duplicate builtin style ID [%s]", id)
}
styleIDs[id] = struct{}{}
light, dark, err := normalizeInlineStyleThemePair(style.Light, style.Dark, "builtin style ["+id+"]")
if err != nil {
return nil, err
}
ret.Styles = append(ret.Styles, &InlineStyleBuiltinStyle{ID: id, Light: light, Dark: dark})
}
sort.Slice(ret.Styles, func(i, j int) bool {
return builtinStyleOrder[ret.Styles[i].ID] < builtinStyleOrder[ret.Styles[j].ID]View on GitHub (pinned to 8641553a1f)
Solutions
- Remove the null element from the builtin.styles array in /storage/inline-styles.json or the API payload.
- Fix the generating code to omit empty entries rather than emitting null.
- If the file is corrupted beyond repair, delete it so defaults are regenerated and reconfigure via the settings UI.
Example fix
// before
"styles": [ {"id": "error", ...}, null ]
// after
"styles": [ {"id": "error", ...} ] Defensive patterns
Strategy: validation
Validate before calling
const styles = config?.builtin?.styles ?? [];
if (styles.some(s => s == null)) {
throw new Error("builtin.styles contains a null entry");
} Type guard
function hasNonNullStyles(cfg) {
return Array.isArray(cfg?.builtin?.styles) && cfg.builtin.styles.every(s => s != null);
} Prevention
- Omit absent style entries instead of writing null placeholders into the styles array.
- Validate the full JSON with a schema (required object items) before persisting inline-styles.json.
When it happens
Trigger: setInlineStylesData or loadInlineStyles with builtin.styles containing a literal `null`, e.g. `"styles": [{"id": "error", ...}, null]`.
Common situations: Hand-edited inline-styles.json with a leftover placeholder; Go/JS code that pre-allocates a 4-element array and fills only some slots; JSON round-trip that serialized missing entries as null.
Related errors
- builtin color must not be null
- inline style must not be null
- duplicate builtin color index [%d]
- invalid builtin style ID [%s]
- duplicate builtin style ID [%s]
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/02bf6277fc6848f2.
Report an issue: GitHub.