{"record":{"id":"ebe034e5ebb0aa41","repo":"siyuan-note/siyuan","slug":"builtin-color-index-d-must-be-between-d-and-d","errorCode":null,"errorMessage":"builtin color index [%d] must be between %d and %d","messagePattern":"builtin color index \\[(.+?)\\] must be between (.+?) and (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/inline_style.go","lineNumber":194,"sourceCode":"\tinlineStylesLock.Lock()\n\tdefer inlineStylesLock.Unlock()\n\n\tif update == nil {\n\t\treturn nil, false, errors.New(\"workspace attribute view palette update must not be null\")\n\t}\n\tcurrent, err := loadInlineStyles()\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tcurrentAV := current.AV\n\tcurrent.AV = &InlineStyleAV{Colors: update.Colors, Order: update.Order}\n\tupdatedIndexes := map[int]struct{}{}\n\tfor _, patch := range update.BuiltinColors {\n\t\tif patch == nil {\n\t\t\treturn nil, false, errors.New(\"workspace attribute view builtin color update must not be null\")\n\t\t}\n\t\tif patch.Index < minBuiltinColorIndex || neutralAVColorIndex < patch.Index {\n\t\t\treturn nil, false, fmt.Errorf(\"builtin color index [%d] must be between %d and %d\", patch.Index,\n\t\t\t\tminBuiltinColorIndex, neutralAVColorIndex)\n\t\t}\n\t\tif _, duplicated := updatedIndexes[patch.Index]; duplicated {\n\t\t\treturn nil, false, fmt.Errorf(\"duplicate workspace attribute view builtin color update [%d]\", patch.Index)\n\t\t}\n\t\tupdatedIndexes[patch.Index] = struct{}{}\n\t\tfiltered := current.Builtin.Colors[:0]\n\t\tfor _, color := range current.Builtin.Colors {\n\t\t\tif color.Index != patch.Index {\n\t\t\t\tfiltered = append(filtered, color)\n\t\t\t}\n\t\t}\n\t\tcurrent.Builtin.Colors = filtered\n\t\tif patch.Customized {\n\t\t\tcurrent.Builtin.Colors = append(current.Builtin.Colors, &InlineStyleBuiltinColor{\n\t\t\t\tIndex: patch.Index,\n\t\t\t\tLight: patch.Light,\n\t\t\t\tDark:  patch.Dark,","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/inline_style.go#L176-L212","documentation":"Builtin palette colors occupy fixed indexes from minBuiltinColorIndex through neutralAVColorIndex (the neutral color). SetWorkspaceAVPalette validates each patch's Index against this closed range and rejects out-of-range patches with this formatted error, preventing updates to undefined palette slots.","triggerScenarios":"Submitting a WorkspaceAVPaletteUpdate whose BuiltinColors patch has Index < minBuiltinColorIndex or Index > neutralAVColorIndex, e.g. a plugin computing indexes from 0 or from 1-based UI positions inconsistently.","commonSituations":"Off-by-one when the UI numbers colors from 1 while the kernel is 0-based (or vice versa); a plugin hard-codes an index beyond the palette size after the palette definition changed; deserialized JSON with a stale index from an older version.","solutions":["Clamp/validate patch.Index against minBuiltinColorIndex..neutralAVColorIndex before sending the update","Align index origin with the kernel constant (check minBuiltinColorIndex and neutralAVColorIndex values in inline_style.go)","Re-fetch the current palette (GetInlineStyles / loadInlineStyles output) and only patch known indexes"],"exampleFix":"// before: 1-based UI index sent to 0-based kernel\nidx := 5 // UI slot 6\nupdate.BuiltinColors = append(update.BuiltinColors,\n\t&model.InlineStyleBuiltinColorPatch{Index: idx, Color: c})\n// after: convert and validate\nidx := 5 - 1\nif idx < model.MinBuiltinColorIndex || idx > model.NeutralAVColorIndex {\n\treturn fmt.Errorf(\"color index %d out of range\", idx)\n}\nupdate.BuiltinColors = append(update.BuiltinColors,\n\t&model.InlineStyleBuiltinColorPatch{Index: idx, Color: c})","handlingStrategy":"validation","validationCode":"if p.Index < model.MinBuiltinColorIndex || p.Index > model.NeutralAVColorIndex {\n\treturn fmt.Errorf(\"index %d outside [%d,%d]\", p.Index, model.MinBuiltinColorIndex, model.NeutralAVColorIndex)\n}","typeGuard":null,"tryCatchPattern":"_, _, err := model.SetWorkspaceAVPalette(update)\nif err != nil && strings.Contains(err.Error(), \"must be between\") {\n\t// clamp/recompute the index and retry\n}","preventionTips":["Match the kernel's index origin (check minBuiltinColorIndex / neutralAVColorIndex) instead of guessing 0- or 1-based","Fetch the current palette and only patch known indexes","Re-validate indexes after kernel upgrades that change palette size"],"tags":["attribute-view","palette","range-check","builtin-colors"],"backgroundTag":"value-out-of-range","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}