{"record":{"id":"79f37d4d1c5760c2","repo":"siyuan-note/siyuan","slug":"attribute-view-custom-colors-must-not-be-empty","errorCode":null,"errorMessage":"attribute view custom colors must not be empty","messagePattern":"attribute view custom colors must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":8898,"sourceCode":"\t\t\tOrder  []string                       `json:\"order\"`\n\t\t}{}\n\t\tif err = gulu.JSON.UnmarshalJSON(data, &decoded); nil != err {\n\t\t\treturn\n\t\t}\n\t\treturn decoded.Colors, decoded.Order, nil\n\t}\n\tcolors = []*av.AttributeViewCustomColor{}\n\terr = gulu.JSON.UnmarshalJSON(data, &colors)\n\treturn\n}\n\nfunc setAttrViewCustomColors(operation *Operation) (err error) {\n\tattrView, err := avParseView(operation.AvID, operation.BlockID)\n\tif nil != err {\n\t\treturn\n\t}\n\tif nil == operation.Data {\n\t\treturn errors.New(\"attribute view custom colors must not be empty\")\n\t}\n\n\tdata, err := gulu.JSON.MarshalJSON(operation.Data)\n\tif nil != err {\n\t\treturn\n\t}\n\tcolors, order, err := parseAttrViewCustomColorsData(data)\n\tif nil != err {\n\t\treturn\n\t}\n\tcolors, err = av.NormalizeAttributeViewCustomColors(colors, true)\n\tif nil != err {\n\t\treturn\n\t}\n\n\toldColors := []*av.AttributeViewCustomColor{}\n\toldOrder := []string{}\n\tif styles, stylesErr := GetInlineStyles(); nil == stylesErr && styles != nil && styles.AV != nil {","sourceCodeStart":8880,"sourceCodeEnd":8916,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/attribute_view.go#L8880-L8916","documentation":"setAttrViewCustomColors guard: the operation payload for setting attribute-view custom colors arrived with operation.Data null. The request must carry the colors object; an absent payload is rejected before marshalling.","triggerScenarios":"Calling the custom-colors API with an operation whose Data field is null/omitted.","commonSituations":"Plugin builds the request dynamically and drops the data field when the palette is empty; a JSON serialization bug omits null fields; clearing colors done by sending null instead of an empty array/object.","solutions":["Pass a non-null Data payload containing the colors (and order) to set","To clear colors, send an empty list in Data rather than null","Validate the request object before sending"],"exampleFix":"// before\nsetCustomColors(avID, null)\n// after\nsetCustomColors(avID, { colors: [], order: [] })","handlingStrategy":"validation","validationCode":"if (payload.data == null) throw new Error(\"custom colors payload must not be null\");","typeGuard":"const hasColors = (op) => op.data != null;","tryCatchPattern":null,"preventionTips":["Always include a Data object, even when empty","Use explicit empty arrays to clear palettes","Validate request objects in a shared request builder"],"tags":["attribute-view","empty-payload","validation"],"backgroundTag":"empty-required-field","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}