siyuan-note/siyuan · error
attribute view custom color index
Error message
attribute view custom color index [%d] is out of range [%d, %d]
What it means
normalizeAttributeViewCustomColor validates that each custom color's Index lies within the inclusive range [CustomColorMinIndex, CustomColorMaxIndex]. An index outside this range cannot be represented in the palette and is rejected with this error naming the offending index and the allowed bounds.
Solutions
- Clamp or reassign the index to a value within [CustomColorMinIndex, CustomColorMaxIndex]
- Renumber all colors sequentially in-range after import/merge
- Check the constants in kernel/av/color.go for the current valid range
Example fix
// before
colors = append(colors, &av.AttributeViewCustomColor{Index: 99, Light: l, Dark: d})
// after
colors = append(colors, &av.AttributeViewCustomColor{Index: av.CustomColorMaxIndex, Light: l, Dark: d}) Defensive patterns
Strategy: validation
Validate before calling
if c.Index < av.CustomColorMinIndex || av.CustomColorMaxIndex < c.Index {
return fmt.Errorf("index %d out of range", c.Index)
} Try / catch
if _, err := av.NormalizeAttributeViewCustomColors(colors, true); err != nil {
if strings.Contains(err.Error(), "is out of range") { renumber(colors) }
} Prevention
- Assign indexes from av.CustomColorMinIndex..av.CustomColorMaxIndex only
- Clamp imported indexes to the valid range
- Read the constants from kernel/av/color.go rather than hardcoding bounds
When it happens
Trigger: Calling NormalizeAttributeViewCustomColors (or resolveColor indirectly) with a color whose Index is negative or greater than CustomColorMaxIndex — commonly from hand-edited palette JSON, imported configs, or an off-by-one index counter.
Common situations: Copying an entry and doubling its index; migrating palettes from older versions with different bounds; plugin code computing index from list length that starts at 1 instead of 0 (or vice versa).
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 must not be null
- attribute view custom colors count exceeds the
- 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/4439c80efa9ac9d9.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/av/color.go:132
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
}
func normalizeAttributeViewColorTheme(theme AttributeViewColorTheme) (ret AttributeViewColorTheme, err error) {
ret.Color = strings.ToLower(strings.TrimSpace(theme.Color))
ret.BackgroundColor = strings.ToLower(strings.TrimSpace(theme.BackgroundColor))View on GitHub (pinned to 9f775e8a12)