siyuan-note/siyuan · error
parse json [ ] to tree failed
Error message
parse json [%s] to tree failed: %w
What it means
fixTreeJSONData (used by LoadTreeWithFix) parses decrypted .sy JSON into a tree with dataparser.ParseJSON. If parsing fails, the file's JSON is not a valid SiYuan document tree, and the raw cause is wrapped with the box+path of the offending file. Unlike LoadTreeByData this path cannot auto-repair, so it hard-fails.
Solutions
- Inspect the wrapped cause to see the JSON syntax/schema error and fix the .sy file accordingly.
- Restore the .sy from sync history, file history, or a backup.
- If the doc is unrecoverable, remove the broken .sy and let the rest of the notebook index; recreate the document.
Example fix
// before: truncated .sy ending in {"ID":"..." (no closing brace)
// after: restore valid JSON from history: complete the object or copy the file from ~/.siyuan/history Defensive patterns
Strategy: try-catch
Validate before calling
// Go: probe before load
if err := treenode.CheckSpecJSON(data); err != nil { /* file invalid — restore from history */ } Try / catch
tree, err := filesys.LoadTreeWithFix(box, p, luteEngine)
if err != nil && strings.Contains(err.Error(), "parse json") {
// restore .sy from file history or mark doc as broken
} Prevention
- Never hand-edit .sy files; use the editor or the API
- Enable file history/sync so corrupted files can be restored
- Validate JSON after any external tool touches the data directory
When it happens
Trigger: Loading a document whose .sy content is malformed JSON, an empty/zero-byte file, or a file whose schema cannot be repaired by dataparser — via kernel load paths using LoadTreeWithFix.
Common situations: Interrupted writes leaving truncated .sy files, manual edits breaking JSON syntax, sync conflicts merging two versions incorrectly, or files damaged by disk errors.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- parse file annotation
- parse imported notebook conf
- block ID must be text
- block operation result must be text, block IDs or null
- block [ ] is not a document
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/6bda6cecc88883ba.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/filesys/tree.go:632
func afterWriteTree(tree *parse.Tree) {
docIAL := parse.IAL2Map(tree.Root.KramdownIAL)
cache.PutDocIALInBox(tree.Path, tree.Box, docIAL)
}
// fixTreeJSONData 订正树 JSON 数据。
func fixTreeJSONData(boxID, p string, jsonData []byte, luteEngine *lute.Lute, dek []byte, encrypted bool) (data []byte, needFix bool, err error) {
if err = treenode.CheckSpecJSON(jsonData); nil != err {
return
}
jsonData, needFix = removeUnescapedUnicodeNull(jsonData)
ret, parseNeedFix, err := dataparser.ParseJSON(jsonData, luteEngine.ParseOptions)
if parseNeedFix {
needFix = true
}
if err != nil {
logging.LogErrorf("parse json [%s] to tree failed: %s", boxID+p, err)
err = fmt.Errorf("parse json [%s] to tree failed: %w", boxID+p, err)
return
}
ret.Box = boxID
ret.Path = p
if err = treenode.CheckSpec(ret); nil != err {
return
}
if err = treenode.RefreshTableCellRichProjection(ret.Root); nil != err {
return
}
if treenode.UpgradeSpec(ret) {
needFix = true
}
// v3.5.1 https://github.com/siyuan-note/siyuan/pull/16657 引入的问题,属性值未转义View on GitHub (pinned to 9f775e8a12)