siyuan-note/siyuan · error

read attribute view custom color usage [%s] failed: %w

Error message

read attribute view custom color usage [%s] failed: %w

What it means

After collecting all attribute-view file paths across notebooks, workspaceAttributeViewCustomColorUsage reads each one via av.ReadAttributeViewCustomColorUsageByPath to gather custom color usage. If reading/parsing one file fails in strict mode, the operation aborts with this wrapped error; otherwise the file is skipped with a logged warning and processing continues with the remaining files.

Source

Thrown at kernel/model/inline_style.go:437

	}
	for _, entry := range entries {
		if !entry.IsDir() || !ast.IsNodeIDPattern(entry.Name()) {
			continue
		}
		if err = appendPaths(filepath.Join(util.DataDir, entry.Name(), "storage", "av")); err != nil {
			if strict {
				return nil, fmt.Errorf("list notebook attribute views [%s] failed: %w", entry.Name(), err)
			}
			logging.LogWarnf("list notebook attribute views [%s] for custom color refresh failed: %s",
				entry.Name(), err)
		}
	}
	sort.Strings(paths)
	for _, path := range paths {
		avID, indexes, readErr := av.ReadAttributeViewCustomColorUsageByPath(path)
		if readErr != nil {
			if strict {
				return nil, fmt.Errorf("read attribute view custom color usage [%s] failed: %w", avID, readErr)
			}
			logging.LogWarnf("read attribute view custom color usage [%s] for refresh failed: %s", avID, readErr)
			continue
		}
		used := ret[avID]
		if used == nil {
			used = map[int]struct{}{}
			ret[avID] = used
		}
		for _, index := range indexes {
			used[index] = struct{}{}
		}
	}
	return ret, nil
}

func isInlineStylesRepoPath(filePath string) bool {
	return filePath == inlineStylesRepoPath

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Identify the failing .av file from the wrapped inner error and restore it from backup/history (SiYuan keeps file history)
  2. Fix file permissions on the storage/av directory and its files
  3. Reopen the affected attribute view in SiYuan so it is re-serialized, or delete the corrupt file if the view is disposable (it will be rebuilt on next save)
  4. Retry the operation; in non-strict mode the corrupt file is skipped automatically

Example fix

// before: strict abort on one corrupt .av file
avID, indexes, readErr := av.ReadAttributeViewCustomColorUsageByPath(path)
if readErr != nil {
    return nil, fmt.Errorf("read attribute view custom color usage [%s] failed: %w", avID, readErr)
}
// after: tolerate single-file failures and keep scanning
if readErr != nil {
    logging.LogWarnf("skip unreadable av [%s]: %s", path, readErr)
    continue
}
Defensive patterns

Strategy: try-catch

Validate before calling

const fs = require('fs');
function avFileLooksValid(path) {
  try { return fs.statSync(path).isFile() && fs.readFileSync(path).length > 0; }
  catch { return false; }
}

Try / catch

try {
  await api.refreshCustomColorUsage();
} catch (e) {
  if (String(e).includes('read attribute view custom color usage')) {
    // restore the named .av from file history, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: setInlineStylesData invokes the custom-color-usage scan in strict mode and one <data>/<notebook>/storage/av/*.av file is corrupted, not valid JSON/gob, locked, or larger/shorter than expected so ReadAttributeViewCustomColorUsageByPath returns an error.

Common situations: A .av file truncated by an interrupted sync or crash, manually edited attribute-view files, permission errors after workspace migration, or an .av file written by an older/newer format version that the parser rejects.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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