{"record":{"id":"b8d2cdd19bd9627b","repo":"siyuan-note/siyuan","slug":"attribute-view-content-is-unavailable","errorCode":null,"errorMessage":"attribute view content is unavailable","messagePattern":"attribute view content is unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/av/av.go","lineNumber":806,"sourceCode":"}\n\nfunc ParseAttributeViewByPath(avJSONPath string) (ret *AttributeView, err error) {\n\treturn parseAttributeViewByPathInBox(avJSONPath, avBoxIDFromPath(avJSONPath))\n}\n\nfunc parseAttributeViewByPathInBox(avJSONPath, boxID string) (ret *AttributeView, err error) {\n\treturn parseAttributeViewByPathInBoxWithOptions(avJSONPath, boxID, true)\n}\n\n// ReadAttributeViewCustomColorUsageByPath 读取属性视图持久化数据中的自定义颜色引用，但不解析派生颜色。\nfunc ReadAttributeViewCustomColorUsageByPath(avJSONPath string) (avID string, indexes []int, err error) {\n\tavID = strings.TrimSuffix(filepath.Base(avJSONPath), filepath.Ext(avJSONPath))\n\tattrView, err := parseAttributeViewByPathInBoxWithOptions(avJSONPath, avBoxIDFromPath(avJSONPath), false)\n\tif err != nil {\n\t\treturn avID, nil, err\n\t}\n\tif attrView == nil {\n\t\treturn avID, nil, errors.New(\"attribute view content is unavailable\")\n\t}\n\treturn avID, attrView.UsedCustomColorIndexes(), nil\n}\n\nfunc parseAttributeViewByPathInBoxWithOptions(avJSONPath, boxID string, resolveColors bool) (ret *AttributeView, err error) {\n\tif !filelock.IsExist(avJSONPath) {\n\t\terr = ErrViewNotFound\n\t\treturn\n\t}\n\trelease, lockErr := holdAVBoxReadLock(boxID)\n\tif lockErr != nil {\n\t\treturn nil, lockErr\n\t}\n\tdefer release()\n\n\tavID := filepath.Base(avJSONPath)\n\tavID = strings.TrimSuffix(avID, filepath.Ext(avID))\n","sourceCodeStart":788,"sourceCodeEnd":824,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/av/av.go#L788-L824","documentation":"When collecting the used custom color indexes of an attribute view, the code derives the avID from the JSON filename and parses the file; if parsing succeeds but returns a nil AttributeView, it reports 'attribute view content is unavailable'. This guards against a degenerate parse result (e.g. empty/blank data that unmarshals to nil) instead of panicking on a nil pointer.","triggerScenarios":"Parsing an attribute view JSON file whose decrypted content yields a nil attrView during used-custom-color collection (parseAttributeViewByPathInBoxWithOptions succeeding but with a nil result).","commonSituations":"A truncated, empty, or partially written .av file after a crash or interrupted sync; an AV file that decrypts to empty content; manually edited or corrupted .av data files in the notebook.","solutions":["Restore the .av file from notebook history or a sync snapshot","Re-index the notebook (rebuild indexes) so the AV data is regenerated from the source document","Verify the .av JSON file is valid JSON and not empty/truncated on disk","If the AV is dispensable, recreate the attribute view from the document"],"exampleFix":"// before\navID, colors, err := av.GetUsedCustomColorIndexesByPath(badPath) // err: content unavailable\n// after\nif err != nil {\n    logging.LogWarnf(\"AV colors unavailable, skipping: %s\", err)\n    return nil // degrade gracefully, e.g. fall back to default colors\n}","handlingStrategy":"fallback","validationCode":"data, err := os.ReadFile(avJSONPath)\nif err != nil || len(bytes.TrimSpace(data)) == 0 {\n    return errors.New(\"av file missing or empty, skip color resolution\")\n}","typeGuard":"func hasAVContent(path string) bool {\n    fi, err := os.Stat(path)\n    return err == nil && fi.Size() > 0\n}","tryCatchPattern":"avID, colors, err := av.GetUsedCustomColorIndexesByPath(path)\nif err != nil {\n    log.Warnf(\"colors unavailable for %s: %v\", path, err)\n    colors = map[string][]string{} // degrade to defaults\n}","preventionTips":["Never hand-edit .av JSON files; use the app/API so writes are atomic","Ensure sync completes and do not read AV files mid-sync","Keep notebook history enabled so truncated files can be restored"],"tags":["go","attribute-view","corrupt-data","parsing"],"backgroundTag":"empty-response-body","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"}