siyuan-note/siyuan · error

list workspace data directory failed: %w

Error message

list workspace data directory failed: %w

What it means

Beyond storage/av, custom color usage discovery also scans workspace data directories (each notebook is a directory named by node ID, checked with ast.IsNodeIDPattern). In strict mode, a ReadDir failure on util.DataDir that is not os.IsNotExist aborts with this wrapped error, preventing an incomplete usage analysis.

Source

Thrown at kernel/model/inline_style.go:416

				continue
			}
			avID := strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name()))
			if ast.IsNodeIDPattern(avID) {
				paths = append(paths, filepath.Join(dir, entry.Name()))
			}
		}
		return nil
	}
	if err = appendPaths(filepath.Join(util.DataDir, "storage", "av")); err != nil {
		if strict {
			return nil, fmt.Errorf("list attribute views failed: %w", err)
		}
		logging.LogWarnf("list attribute views for custom color refresh failed: %s", err)
	}
	entries, readErr := os.ReadDir(util.DataDir)
	if readErr != nil && !os.IsNotExist(readErr) {
		if strict {
			return nil, fmt.Errorf("list workspace data directory failed: %w", readErr)
		}
		logging.LogWarnf("list workspace data directory for custom color refresh failed: %s", readErr)
	}
	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)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Verify util.DataDir (the workspace data/ folder) exists, is a directory, and is readable by the kernel process
  2. Remount or repair the volume hosting the workspace if ReadDir reports I/O errors
  3. Fix ownership/permissions after restoring or copying the workspace (e.g. chown -R) and retry
  4. If the error is transient (mount reconnected), simply retry the palette update

Example fix

# before
drwxr--r-- root data/   # kernel user cannot read
# after
chown -R siyuan:siyuan data/ && chmod -R u+rwX data/
Defensive patterns

Strategy: fallback

Validate before calling

if fi, err := os.Stat(util.DataDir); err != nil || !fi.IsDir() {
    return fmt.Errorf("workspace data dir unusable: %v", err)
}

Try / catch

usage, err := model.WorkspaceAttributeViewCustomColorUsage(true)
if err != nil {
    log.Warnf("skipping palette changes: workspace data dir unreadable: %v", err)
    return
}

Prevention

When it happens

Trigger: util.DataDir unreadable due to permissions; DataDir exists but ReadDir fails with EIO/EACCES (not ENOENT, which is tolerated); DataDir replaced by a file or a broken mount.

Common situations: Workspace data directory on a failed/unmounted network share; running the kernel without read access to the data dir after a user switch; filesystem corruption.

Related errors


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