siyuan-note/siyuan · error
invalid option color
Error message
invalid option color
What it means
Option colors must match one of SiYuan's canonical filter/option colors. attrView.FilterColorValue normalizes a submitted color, and if normalization changes it the value was not one of the accepted palette strings, so the update is rejected.
Solutions
- Use one of the accepted option/filter color values (the palette shown in the SiYuan field editor)
- Drop the color field so the default/normalized color is applied
- Normalize via the same FilterColorValue logic client-side before sending
Example fix
// before
{"name":"Todo","color":"#e54545"}
// after
{"name":"Todo","color":"4"} Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED_COLORS = new Set(["","1","2","3","4","5","6","7","8","9","10","11","12","13"]);
if (!ALLOWED_COLORS.has(option.color)) throw new Error(`unsupported option color: ${option.color}`); Prevention
- Only offer the SiYuan palette colors in your UI
- Never send raw hex colors for select options
When it happens
Trigger: Updating options ('options' setting) or renaming an option ('optionUpdate' with color) where Color is an arbitrary hex string like "#ff0000", an out-of-range index, or a non-canonical value.
Common situations: Plugin code picking its own palette colors; importer mapping another app's tag colors 1:1; frontend sending a CSS color instead of SiYuan's filter-color value.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- duplicate option name
- each option requires a nonempty name
- invalid background color
- invalid dark theme of attribute view custom color
- invalid foreground color
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/4f96aae2671c3d03.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view_key_config.go:211
func updateAttributeViewKeyOptions(attrView *av.AttributeView, key *av.Key, op *Operation, setting string, value any) error {
if "options" == setting {
var options []*av.SelectOption
if err := decodeAttributeViewKeyConfig(value, &options); nil != err {
return err
}
if 0 == len(options) {
return errors.New("options must not be empty; use optionRemove to delete existing options")
}
names := map[string]bool{}
for _, option := range options {
if nil == option || "" == strings.TrimSpace(option.Name) {
return errors.New("each option requires a nonempty name")
}
if names[option.Name] {
return errors.New("duplicate option name")
}
if attrView.FilterColorValue(option.Color) != option.Color {
return errors.New("invalid option color")
}
names[option.Name] = true
}
op.Data = options
return updateAttributeViewColumnOptions(op)
}
if "optionRemove" == setting {
name, ok := value.(string)
if !ok || nil == key.GetOption(name) {
return errors.New("optionRemove must name an existing option")
}
op.Data = name
return removeAttributeViewColumnOption(op)
}
var config struct {
Name string `json:"name"`
NewName *string `json:"newName"`
Color *string `json:"color"`View on GitHub (pinned to 9f775e8a12)