siyuan-note/siyuan · error
attribute view custom color must not be null
Error message
attribute view custom color must not be null
What it means
normalizeAttributeViewCustomColor rejects a nil color entry with this sentinel message. A null element inside the custom colors array carries no index or theme data and cannot be normalized, so it is treated as invalid input.
Source
Thrown at kernel/av/color.go:129
}
continue
}
indexes[normalized.Index] = struct{}{}
ret = append(ret, normalized)
}
sort.Slice(ret, func(i, j int) bool {
return ret[i].Index < ret[j].Index
})
if nil == ret {
ret = []*AttributeViewCustomColor{}
}
return
}
func normalizeAttributeViewCustomColor(color *AttributeViewCustomColor) (ret *AttributeViewCustomColor, err error) {
if nil == color {
return nil, errors.New("attribute view custom color must not be null")
}
if color.Index < CustomColorMinIndex || CustomColorMaxIndex < color.Index {
return nil, fmt.Errorf("attribute view custom color index [%d] is out of range [%d, %d]",
color.Index, CustomColorMinIndex, CustomColorMaxIndex)
}
ret = &AttributeViewCustomColor{Index: color.Index, Hidden: color.Hidden}
ret.Light, err = normalizeAttributeViewColorTheme(color.Light)
if nil != err {
return nil, fmt.Errorf("invalid light theme of attribute view custom color [%d]: %w", color.Index, err)
}
ret.Dark, err = normalizeAttributeViewColorTheme(color.Dark)
if nil != err {
return nil, fmt.Errorf("invalid dark theme of attribute view custom color [%d]: %w", color.Index, err)
}
return
}
View on GitHub (pinned to 8641553a1f)
Solutions
- Filter out nil entries before calling NormalizeAttributeViewCustomColors.
- Fix the JSON producer so absent colors are omitted from the array instead of written as null.
- If the null came from decoding into a fixed-size array, switch to a variadic slice or pre-size the slice correctly.
- In non-strict mode the entry still errors at normalizeAttributeViewCustomColor — filtering nils is required in both modes.
Example fix
// before
ret, err := av.NormalizeAttributeViewCustomColors(colors, true) // colors contains nil
// after
filtered := make([]*av.AttributeViewCustomColor, 0, len(colors))
for _, c := range colors {
if c != nil {
filtered = append(filtered, c)
}
}
ret, err := av.NormalizeAttributeViewCustomColors(filtered, true) Defensive patterns
Strategy: type-guard
Validate before calling
func nonNil(colors []*av.AttributeViewCustomColor) []*av.AttributeViewCustomColor {
out := colors[:0]
for _, c := range colors { if c != nil { out = append(out, c) } }
return out
} Type guard
func isValidColor(c *av.AttributeViewCustomColor) bool { return c != nil } Try / catch
if _, err := av.NormalizeAttributeViewCustomColors(colors, true); err != nil && strings.Contains(err.Error(), "must not be null") {
// filter nils and retry
} Prevention
- Filter nil entries from color slices before normalizing
- Never serialize null elements into the customColors JSON array
- Check JSON decoding results for zero-fill holes in fixed-size arrays
When it happens
Trigger: Passing a slice containing nil to av.NormalizeAttributeViewCustomColors (each element goes through normalizeAttributeViewCustomColor, color.go:129); JSON decoding that left null holes in the colors array (e.g. `[null, {...}]` or oversized arrays zero-filled).
Common situations: JSON like "customColors":[null,...] produced by another tool or a buggy writer; Go code building the slice with a nil entry from a failed lookup; a migration importing palettes where missing entries became null instead of being skipped.
Related errors
- attribute view custom colors count exceeds the %d item limit
- duplicated attribute view custom color index [%d]
- attribute view custom color index [%d] is out of range [%d,
- invalid light theme of attribute view custom color [%d]: %w
- ErrFilterTooDeep
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/d6fdc7f9fe72034d.
Report an issue: GitHub.