siyuan-note/siyuan · error
attribute view custom colors count exceeds the
Error message
attribute view custom colors count exceeds the %d item limit
What it means
NormalizeAttributeViewCustomColors validates and normalizes a database (attribute view) custom color list. In strict mode, if the input list contains more than MaxCustomColors entries, it rejects the entire list rather than truncating. This protects the persisted palette configuration from silently growing beyond the supported limit.
Solutions
- Trim the colors slice to at most MaxCustomColors entries before calling the API
- Merge duplicate or unused colors to reduce the count below the limit
- If the palette came from a config/history file, remove excess entries from that file
Example fix
// before
ret, err := av.NormalizeAttributeViewCustomColors(colors, true)
// after
if len(colors) > av.MaxCustomColors {
colors = colors[:av.MaxCustomColors]
}
ret, err := av.NormalizeAttributeViewCustomColors(colors, true) Defensive patterns
Strategy: validation
Validate before calling
if len(colors) > av.MaxCustomColors {
return fmt.Errorf("too many colors: %d > %d", len(colors), av.MaxCustomColors)
} Try / catch
if _, err := av.NormalizeAttributeViewCustomColors(colors, true); err != nil {
if strings.Contains(err.Error(), "item limit") { colors = colors[:av.MaxCustomColors] }
} Prevention
- Check len(colors) against MaxCustomColors before appending
- Merge duplicate colors instead of adding new entries
- Never hand-edit palette files without counting entries
When it happens
Trigger: Calling setAttrViewCustomColors, customColorPalette, or decodeHistoricalWorkspacePalette with a palette whose length exceeds MaxCustomColors while strict=true; decoding a workspace palette file that was hand-edited or produced by an older/newer version without the cap.
Common situations: Hand-editing the workspace palette JSON and adding too many colors; importing palette settings from another workspace or version that did not enforce the limit; plugin code appending custom colors without checking MaxCustomColors.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- at least one visible view is required
- attribute view custom color index
- attribute view custom color must not be null
- attribute view custom colors must not be empty
- attribute view is not unused
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/d58892a4d5909f85.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/av/color.go:96
// UnmarshalJSON 忽略外部输入中的派生颜色,派生颜色只能由内核根据数据库调色板生成。
func (value *ValueSelect) UnmarshalJSON(data []byte) error {
decoded := struct {
Content string `json:"content"`
Color string `json:"color"`
}{}
if err := json.Unmarshal(data, &decoded); nil != err {
return err
}
value.Content = decoded.Content
value.Color = decoded.Color
value.ResolvedColor = nil
return nil
}
// NormalizeAttributeViewCustomColors 校验并规范化数据库自定义颜色。
func NormalizeAttributeViewCustomColors(colors []*AttributeViewCustomColor, strict bool) (ret []*AttributeViewCustomColor, err error) {
if strict && MaxCustomColors < len(colors) {
return nil, fmt.Errorf("attribute view custom colors count exceeds the %d item limit", MaxCustomColors)
}
indexes := map[int]struct{}{}
for _, color := range colors {
normalized, normalizeErr := normalizeAttributeViewCustomColor(color)
if nil != normalizeErr {
if strict {
return nil, normalizeErr
}
continue
}
if _, ok := indexes[normalized.Index]; ok {
if strict {
return nil, fmt.Errorf("duplicated attribute view custom color index [%d]", normalized.Index)
}
continue
}
indexes[normalized.Index] = struct{}{}View on GitHub (pinned to 9f775e8a12)