siyuan-note/siyuan · error
unmarshal inline styles failed: %w
Error message
unmarshal inline styles failed: %w
What it means
loadInlineStyles parses the inline-styles file with gulu.JSON.UnmarshalJSON into the InlineStyles struct. If the bytes are not valid JSON or do not match the expected structure, parsing fails and this wrapped error is returned, preventing malformed data from entering the styling subsystem.
Source
Thrown at kernel/model/inline_style.go:471
func isInlineStylesRepoPath(filePath string) bool {
return filePath == inlineStylesRepoPath
}
func loadInlineStyles() (ret *InlineStyles, err error) {
ret = newEmptyInlineStyles()
data, err := filelock.ReadFile(inlineStylesPath())
if os.IsNotExist(err) {
return ret, nil
}
if err != nil {
return nil, fmt.Errorf("read inline styles failed: %w", err)
}
if maxInlineStylesFileSize < len(data) {
return nil, fmt.Errorf("inline styles file exceeds the %d byte limit", maxInlineStylesFileSize)
}
if err = gulu.JSON.UnmarshalJSON(data, ret); err != nil {
return nil, fmt.Errorf("unmarshal inline styles failed: %w", err)
}
if ret.Version != 1 && ret.Version != InlineStylesVersion {
return nil, fmt.Errorf("unsupported inline styles version [%d]", ret.Version)
}
ret.Styles, err = normalizeInlineStyles(ret.Styles, false)
if err != nil {
return nil, fmt.Errorf("invalid inline styles data: %w", err)
}
ret.Builtin, err = normalizeInlineStyleBuiltin(ret.Builtin)
if err != nil {
return nil, fmt.Errorf("invalid inline styles data: %w", err)
}
ret.Order = normalizeInlineStyleOrder(ret.Order, ret.Styles)
ret.AV, err = normalizeInlineStyleAV(ret.AV, false)
if err != nil {
return nil, fmt.Errorf("invalid inline styles data: %w", err)
}
ret.Version = InlineStylesVersionView on GitHub (pinned to 8641553a1f)
Solutions
- Validate the file as JSON (e.g. with a JSON linter) and fix the syntax error, or restore it from file history/backup
- If the styles are not valuable, delete the file; the next load returns an empty default structure and it is recreated on next save
- Ensure the file is UTF-8 without BOM and completely written (no truncation)
- Avoid hand-editing the file while SiYuan is running; use the in-app style editor instead
Example fix
// before: truncated/corrupt JSON on disk
{"version":2,"styles":[{"id":"2024...
// after: complete valid JSON restored from history
{"version":2,"styles":[],"builtin":{},"order":[],"av":{}} Defensive patterns
Strategy: validation
Validate before calling
function inlineStylesIsValidJSON(path) {
try { JSON.parse(require('fs').readFileSync(path, 'utf8')); return true; }
catch { return false; }
} Try / catch
try {
const styles = await api.getInlineStyles();
} catch (e) {
if (String(e).includes('unmarshal inline styles failed')) {
// restore the file from history or delete it to reset to defaults
} else throw e;
} Prevention
- Do not hand-edit the inline-styles file while the app is running
- Save edits as UTF-8 without BOM
- Use a JSON linter before putting an edited file back
When it happens
Trigger: Any loader-calling API runs while the inline-styles file contains invalid JSON: truncated writes from a crash, manual editing mistakes, encoding issues (BOM, non-UTF8), or the file being overwritten by another tool.
Common situations: Power loss mid-write leaving a half-written file, a user hand-editing the JSON and introducing a syntax error, sync conflicts merging two JSON versions textually, or the file being replaced with exported HTML/log content by mistake.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- tool arguments are not valid JSON: %w
- %w: %v
- parse json [%s] to tree failed: %w
- unmarshal AI editor actions failed: %w
- unmarshal box document metadata failed: %w
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/a788f86fe5f6ae91.
Report an issue: GitHub.