siyuan-note/siyuan · error

read inline styles failed: %w

Error message

read inline styles failed: %w

What it means

setInlineStylesData reads the existing inline-styles file (via filelock.ReadFile) to detect no-op writes (byte-equal short-circuit) and to preserve state. Any read error other than os.IsNotExist aborts the update. This means I/O problems — permissions, device errors, lock conflicts — surface wrapped in this message.

Source

Thrown at kernel/model/inline_style.go:288

				if _, used := indexes[index]; used {
					return nil, false, fmt.Errorf("attribute view custom color [%d] is still in use by attribute view [%s]",
						index, avID)
				}
			}
		}
	}
	data, err := gulu.JSON.MarshalIndentJSON(ret, "", "  ")
	if err != nil {
		return nil, false, fmt.Errorf("marshal inline styles failed: %w", err)
	}
	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)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Check and fix filesystem permissions on the workspace storage directory and the styles file
  2. Confirm the disk/mount is writable (read-only mounts, full disks, disconnected network drives)
  3. Close programs holding the file (backup/AV tools) and retry
  4. As a last resort, back up and remove the unreadable file — the setter will treat it as not-exist and recreate it, losing old palette customizations

Example fix

# before
-rw------- root storage/inline_styles  # unreadable by kernel user
# after
chown siyuan:siyuan storage/inline_styles && chmod 600 storage/inline_styles
Defensive patterns

Strategy: retry

Validate before calling

if f, err := os.Open(stylesPath); err != nil && !os.IsNotExist(err) {
    return fmt.Errorf("styles file unreadable before write: %w", err)
} else if f != nil { f.Close() }

Try / catch

_, _, err := model.SetInlineStyles(styles)
if err != nil && strings.HasPrefix(err.Error(), "read inline styles failed") {
    time.Sleep(200 * time.Millisecond)
    _, _, err = model.SetInlineStyles(styles) // retry once for transient lock/IO
}

Prevention

When it happens

Trigger: storage/inline_styles exists but is unreadable (permissions changed, file owned by another user, read-only mount); filelock contention or underlying FS error; corrupted filesystem returning EIO.

Common situations: Running the kernel as a different user after a sudo session; workspace on a network/external drive that went read-only; Windows file locked by backup software (depending on filelock behavior).

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/f7773e9c4eb1010d. Report an issue: GitHub.