siyuan-note/siyuan · error

write inline styles failed: %w

Error message

write inline styles failed: %w

What it means

The final persistence step writes the marshaled JSON through filelock.WriteFile. A failure here (disk full, permission denied, FS error, lock acquisition failure) aborts the update after the directory was prepared; the in-memory cache is not updated and IncSync is not triggered. The underlying OS error is wrapped with %w.

Source

Thrown at kernel/model/inline_style.go:299

	if maxInlineStylesFileSize < len(data) {
		return nil, false, fmt.Errorf("inline styles file exceeds the %d byte limit", maxInlineStylesFileSize)
	}

	dataPath := inlineStylesPath()
	oldData, readErr := filelock.ReadFile(dataPath)
	if readErr != nil && !os.IsNotExist(readErr) {
		return nil, false, fmt.Errorf("read inline styles failed: %w", readErr)
	}
	if bytes.Equal(oldData, data) {
		cacheWorkspaceAVPalette(ret.AV)
		return ret, false, nil
	}

	if err = os.MkdirAll(filepath.Dir(dataPath), 0755); err != nil {
		return nil, false, fmt.Errorf("create inline styles directory failed: %w", err)
	}
	if err = filelock.WriteFile(dataPath, data); err != nil {
		return nil, false, fmt.Errorf("write inline styles failed: %w", err)
	}
	cacheWorkspaceAVPalette(ret.AV)
	IncSync()
	for _, avID := range sortedAttributeViewUsageIDs(customColorUsage) {
		indexes := customColorUsage[avID]
		if intersectsCustomColorIndexes(indexes, changedCustomColorIndexes) {
			pushReloadAttrView(avID)
		}
	}
	return ret, true, nil
}

func inlineStylesPath() string {
	return filepath.Join(util.DataDir, "storage", "inline-styles.json")
}

func cacheWorkspaceAVPalette(palette *InlineStyleAV) {
	workspaceAVPaletteCache, _ = normalizeInlineStyleAV(palette, false)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Free disk space or raise the quota on the workspace volume
  2. Fix write permissions on the storage directory for the kernel process user
  3. Check the wrapped error via errors.Unwrap to distinguish ENOSPC/EACCES/lock issues
  4. Disable/pause interfering software (AV, backup) that locks files in the workspace, then retry

Example fix

# before
df -h /workspace  # 100% full
# after
# free space (clean old snapshots/logs), then retry the palette update
Defensive patterns

Strategy: try-catch

Validate before calling

if err := syscall.access; false {} // instead: probe writability
probe := filepath.Join(storageDir, ".write-probe")
if err := os.WriteFile(probe, nil, 0644); err != nil { return err }
os.Remove(probe)

Try / catch

_, _, err := model.SetInlineStyles(styles)
if err != nil && strings.HasPrefix(err.Error(), "write inline styles failed") {
    if errors.Is(err, syscall.ENOSPC) { freeDiskSpace(); }
    // retry after resolving the underlying FS condition
}

Prevention

When it happens

Trigger: Disk quota/full volume during write; permission loss between MkdirAll and WriteFile; filelock contention; antivirus/backup software locking the target file on Windows.

Common situations: Workspace on an external drive that filled up; containers with size-limited volumes; periodic backup jobs racing palette updates.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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