siyuan-note/siyuan · error
inline style must not be null
Error message
inline style must not be null
What it means
normalizeInlineStyles validates the workspace inline-style list before saving or loading it. A nil element inside the styles slice is rejected outright because the normalizer dereferences style.ID/Name/Light/Dark and a null entry would represent corrupt configuration. The whole save/load operation fails fast with this error.
Source
Thrown at kernel/model/inline_style.go:651
if _, ok := hidden[index]; !ok {
ret = append(ret, index)
}
}
if len(ret) == 0 {
return []int{neutralAVColorIndex}
}
return ret
}
func normalizeInlineStyles(styles []*InlineStyle, generateIDs bool) (ret []*InlineStyle, err error) {
if maxInlineStyles < len(styles) {
return nil, fmt.Errorf("inline styles count exceeds the %d item limit", maxInlineStyles)
}
ret = make([]*InlineStyle, 0, len(styles))
ids := make(map[string]struct{}, len(styles))
for _, style := range styles {
if style == nil {
return nil, errors.New("inline style must not be null")
}
id := strings.TrimSpace(style.ID)
if id == "" && generateIDs {
for {
id = ast.NewNodeID()
if _, exists := ids[id]; !exists {
break
}
}
}
if !ast.IsNodeIDPattern(id) {
return nil, fmt.Errorf("invalid inline style ID [%s]", id)
}
if _, exists := ids[id]; exists {
return nil, fmt.Errorf("duplicate inline style ID [%s]", id)
}
ids[id] = struct{}{}View on GitHub (pinned to 8641553a1f)
Solutions
- Remove null entries from the styles array before calling the set API (filter on the client or in a preprocessing step).
- Fix the inline-styles JSON file on disk (remove the null element) so loadInlineStyles succeeds.
- Fix the producer code that appends to the slice to skip nil items instead of relying on later filtering.
Example fix
// before
styles := make([]*InlineStyle, 2)
styles[0] = &InlineStyle{ID: "20240101120000-abcdefg", Name: "mark"}
api.SetInlineStyles(styles) // styles[1] is nil -> error
// after
styles := make([]*InlineStyle, 0, 2)
styles = append(styles, &InlineStyle{ID: "20240101120000-abcdefg", Name: "mark"})
api.SetInlineStyles(styles) Defensive patterns
Strategy: validation
Validate before calling
const filtered = styles.filter(s => s != null); if (filtered.length !== styles.length) throw new Error('style list contains null entries'); Type guard
const isInlineStyle = (s: unknown): s is InlineStyle => !!s && typeof s === 'object' && 'ID' in s;
Try / catch
try { await fetchPost('/api/attr/setInlineStyles', {styles}) } catch (e) { if (String(e).includes('must not be null')) { styles = styles.filter(Boolean); /* retry */ } } Prevention
- Always build the styles array with append/push, never pre-allocated fixed slots left nil
- Filter nulls before serializing the payload
- Never hand-edit the inline-styles JSON without re-validating the array
When it happens
Trigger: Passing a []*InlineStyle that contains a nil element to setInlineStylesData (e.g. via the API /api/attr/setInlineStyles with a JSON array containing a null), or a persisted inline-styles JSON file whose array contains a null entry read back by loadInlineStyles.
Common situations: Hand-editing or programmatically generating the inline-styles JSON and leaving a trailing/null element in the array; client code building the list with a fixed-size slice where unused slots stay nil; partial JSON merges that insert null placeholders.
Related errors
- builtin color must not be null
- builtin style must not be null
- local storage value for key [%s] must not be empty
- wrong layout type
- filter nesting depth exceeds the maximum allowed
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/7e5641872e211024.
Report an issue: GitHub.