{"record":{"id":"f41a442db268c29d","repo":"siyuan-note/siyuan","slug":"attribute-view-custom-color-d-is-still-in-use-b","errorCode":null,"errorMessage":"attribute view custom color [%d] is still in use by attribute view [%s]","messagePattern":"attribute view custom color \\[(.+?)\\] is still in use by attribute view \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/inline_style.go","lineNumber":271,"sourceCode":"\t\tVersion: InlineStylesVersion,\n\t\tStyles:  normalizedStyles,\n\t\tBuiltin: normalizedBuiltin,\n\t\tOrder:   normalizeInlineStyleOrder(styles.Order, normalizedStyles),\n\t\tAV:      normalizedAV,\n\t}\n\tchangedCustomColorIndexes := changedAttributeViewCustomColorIndexes(currentAV.Colors, ret.AV.Colors)\n\tvar customColorUsage map[string]map[int]struct{}\n\tif 0 < len(changedCustomColorIndexes) {\n\t\tremovedIndexes := removedAttributeViewCustomColorIndexes(currentAV.Colors, ret.AV.Colors)\n\t\tcustomColorUsage, err = workspaceAttributeViewCustomColorUsage(0 < len(removedIndexes))\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tfor _, avID := range sortedAttributeViewUsageIDs(customColorUsage) {\n\t\t\tindexes := customColorUsage[avID]\n\t\t\tfor index := range removedIndexes {\n\t\t\t\tif _, used := indexes[index]; used {\n\t\t\t\t\treturn nil, false, fmt.Errorf(\"attribute view custom color [%d] is still in use by attribute view [%s]\",\n\t\t\t\t\t\tindex, avID)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tdata, err := gulu.JSON.MarshalIndentJSON(ret, \"\", \"  \")\n\tif err != nil {\n\t\treturn nil, false, fmt.Errorf(\"marshal inline styles failed: %w\", err)\n\t}\n\tif maxInlineStylesFileSize < len(data) {\n\t\treturn nil, false, fmt.Errorf(\"inline styles file exceeds the %d byte limit\", maxInlineStylesFileSize)\n\t}\n\n\tdataPath := inlineStylesPath()\n\toldData, readErr := filelock.ReadFile(dataPath)\n\tif readErr != nil && !os.IsNotExist(readErr) {\n\t\treturn nil, false, fmt.Errorf(\"read inline styles failed: %w\", readErr)\n\t}","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/inline_style.go#L253-L289","documentation":"When updating inline styles, removed custom color entries are checked against workspaceAttributeViewCustomColorUsage, which maps attribute-view IDs to the custom color indexes they still reference. If a color index slated for removal is used by any attribute view, the write is aborted so cells do not lose their color mapping. The error names the offending index and the AV ID that uses it.","triggerScenarios":"Calling SetInlineStyles/SetWorkspaceAVPalette with a styles payload that deletes a custom color entry while some .av file still references that color index in its cell styles.","commonSituations":"Hand-editing the inline-styles file to prune 'unused' colors without checking attribute views; a script regenerating the palette from scratch while notebooks contain AVs using old indexes; restoring a partial palette backup alongside newer .av files.","solutions":["Re-add the in-use custom color entry (same index) to the styles payload, or keep the existing palette untouched","Open the named attribute view and change its cells to another color first, then retry the removal","Run workspaceAttributeViewCustomColorUsage yourself to see which indexes are safe to delete before constructing the payload","If the .av references are stale (AV deleted but file remains), clean up the orphaned .av file, then retry"],"exampleFix":"// before\nstyles.Styles = remainingColors // dropped index 3, but AV 20240... still uses it\n// after\nstyles.Styles[\"3\"] = existingColorEntry // keep colors still referenced by attribute views\nret, _, err := SetInlineStyles(styles)","handlingStrategy":"validation","validationCode":"usage, err := model.WorkspaceAttributeViewCustomColorUsage(true)\nif err != nil { return err }\nfor idx := range removedIndexes {\n    for avID, indexes := range usage {\n        if _, used := indexes[idx]; used { return fmt.Errorf(\"color %d in use by %s\", idx, avID) }\n    }\n}","typeGuard":null,"tryCatchPattern":"_, _, err := model.SetInlineStyles(styles)\nif err != nil && strings.Contains(err.Error(), \"is still in use by attribute view\") {\n    // parse the index/AV ID from the message, re-add the color or update the AV, then retry\n}","preventionTips":["Always compute custom-color usage before pruning palette entries","Change attribute-view cells to other colors before deleting their custom color","Keep a backup of the inline-styles file before bulk palette edits"],"tags":["go","attribute-view","conflict","data-integrity"],"backgroundTag":"conflicting-state","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"}