siyuan-note/siyuan · error

attribute view content is unavailable

Error message

attribute view content is unavailable

What it means

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.

Source

Thrown at kernel/av/av.go:806

}

func ParseAttributeViewByPath(avJSONPath string) (ret *AttributeView, err error) {
	return parseAttributeViewByPathInBox(avJSONPath, avBoxIDFromPath(avJSONPath))
}

func parseAttributeViewByPathInBox(avJSONPath, boxID string) (ret *AttributeView, err error) {
	return parseAttributeViewByPathInBoxWithOptions(avJSONPath, boxID, true)
}

// ReadAttributeViewCustomColorUsageByPath 读取属性视图持久化数据中的自定义颜色引用,但不解析派生颜色。
func ReadAttributeViewCustomColorUsageByPath(avJSONPath string) (avID string, indexes []int, err error) {
	avID = strings.TrimSuffix(filepath.Base(avJSONPath), filepath.Ext(avJSONPath))
	attrView, err := parseAttributeViewByPathInBoxWithOptions(avJSONPath, avBoxIDFromPath(avJSONPath), false)
	if err != nil {
		return avID, nil, err
	}
	if attrView == nil {
		return avID, nil, errors.New("attribute view content is unavailable")
	}
	return avID, attrView.UsedCustomColorIndexes(), nil
}

func parseAttributeViewByPathInBoxWithOptions(avJSONPath, boxID string, resolveColors bool) (ret *AttributeView, err error) {
	if !filelock.IsExist(avJSONPath) {
		err = ErrViewNotFound
		return
	}
	release, lockErr := holdAVBoxReadLock(boxID)
	if lockErr != nil {
		return nil, lockErr
	}
	defer release()

	avID := filepath.Base(avJSONPath)
	avID = strings.TrimSuffix(avID, filepath.Ext(avID))

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Restore the .av file from notebook history or a sync snapshot
  2. Re-index the notebook (rebuild indexes) so the AV data is regenerated from the source document
  3. Verify the .av JSON file is valid JSON and not empty/truncated on disk
  4. If the AV is dispensable, recreate the attribute view from the document

Example fix

// before
avID, colors, err := av.GetUsedCustomColorIndexesByPath(badPath) // err: content unavailable
// after
if err != nil {
    logging.LogWarnf("AV colors unavailable, skipping: %s", err)
    return nil // degrade gracefully, e.g. fall back to default colors
}
Defensive patterns

Strategy: fallback

Validate before calling

data, err := os.ReadFile(avJSONPath)
if err != nil || len(bytes.TrimSpace(data)) == 0 {
    return errors.New("av file missing or empty, skip color resolution")
}

Type guard

func hasAVContent(path string) bool {
    fi, err := os.Stat(path)
    return err == nil && fi.Size() > 0
}

Try / catch

avID, colors, err := av.GetUsedCustomColorIndexesByPath(path)
if err != nil {
    log.Warnf("colors unavailable for %s: %v", path, err)
    colors = map[string][]string{} // degrade to defaults
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/b8d2cdd19bd9627b. Report an issue: GitHub.