siyuan-note/siyuan · error
create inline styles directory failed: %w
Error message
create inline styles directory failed: %w
What it means
Before writing the new styles JSON, setInlineStylesData ensures the parent directory (under the workspace storage path) exists via os.MkdirAll. If directory creation fails (permissions, read-only FS, path is a file), the write aborts with this wrapped error.
Source
Thrown at kernel/model/inline_style.go:296
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)
}
}
return ret, true, nil
}
func inlineStylesPath() string {
return filepath.Join(util.DataDir, "storage", "inline-styles.json")
}View on GitHub (pinned to 8641553a1f)
Solutions
- Check that filepath.Dir(inlineStylesPath()) is not occupied by a regular file; remove/rename the file
- Grant the kernel process write permission on the workspace storage directory (chown/chmod)
- Remount the workspace volume read-write if it is read-only
- Inspect the wrapped OS error (permission denied vs no space vs not a directory) to target the fix
Example fix
# before storage/inline_styles/ -> actually a regular file # after mv storage/inline_styles storage/inline_styles.bak && mkdir storage/inline_styles
Defensive patterns
Strategy: try-catch
Validate before calling
dir := filepath.Dir(stylesPath)
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s is not a directory", dir)
} Try / catch
_, _, err := model.SetInlineStyles(styles)
if err != nil && strings.HasPrefix(err.Error(), "create inline styles directory failed") {
return fmt.Errorf("check storage dir permissions/mount: %w", err)
} Prevention
- Ensure the workspace volume is mounted read-write before starting the kernel
- Never place a regular file where the storage directory is expected
- Pre-provision the storage directory with correct ownership in container images
When it happens
Trigger: The target directory path exists as a regular file; the workspace volume is read-only or full; the process lacks write permission on the storage parent directory; SELinux/AppArmor denies creation.
Common situations: Docker containers with a read-only or mis-mounted workspace; a stray file named like the expected directory after a bad restore; running as non-root against a root-owned workspace.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- create import dir failed:
- read session file failed: %w
- create session dir failed: %w
- create AI editor actions directory failed: %w
- mkdir box conf dir failed: %w
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/9913ea25bffaf817.
Report an issue: GitHub.