{"record":{"id":"6bda6cecc88883ba","repo":"siyuan-note/siyuan","slug":"parse-json-s-to-tree-failed-w","errorCode":null,"errorMessage":"parse json [%s] to tree failed: %w","messagePattern":"parse json \\[(.+?)\\] to tree failed: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/filesys/tree.go","lineNumber":546,"sourceCode":"\t}\n\treturn dst, len(dst) != n\n}\n\nfunc afterWriteTree(tree *parse.Tree) {\n\tdocIAL := parse.IAL2Map(tree.Root.KramdownIAL)\n\tcache.PutDocIALInBox(tree.Path, tree.Box, docIAL)\n}\n\n// fixTreeJSONData 订正树 JSON 数据。\nfunc fixTreeJSONData(boxID, p string, jsonData []byte, luteEngine *lute.Lute, dek []byte, encrypted bool) (data []byte, needFix bool, err error) {\n\tjsonData, needFix = removeUnescapedUnicodeNull(jsonData)\n\tret, parseNeedFix, err := dataparser.ParseJSON(jsonData, luteEngine.ParseOptions)\n\tif parseNeedFix {\n\t\tneedFix = true\n\t}\n\tif err != nil {\n\t\tlogging.LogErrorf(\"parse json [%s] to tree failed: %s\", boxID+p, err)\n\t\terr = fmt.Errorf(\"parse json [%s] to tree failed: %w\", boxID+p, err)\n\t\treturn\n\t}\n\n\tret.Box = boxID\n\tret.Path = p\n\n\tif err = treenode.CheckSpec(ret); errors.Is(err, treenode.ErrSpecTooNew) {\n\t\treturn\n\t}\n\n\tif treenode.UpgradeSpec(ret) {\n\t\tneedFix = true\n\t}\n\n\t// v3.5.1 https://github.com/siyuan-note/siyuan/pull/16657 引入的问题，属性值未转义\n\t// v3.5.2 https://github.com/siyuan-note/siyuan/issues/16686 进行了修复，并加了订正逻辑 https://github.com/siyuan-note/siyuan/pull/16712\n\t// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-ff66-236v-p4fg XSS 漏洞：\"title\": \"&amp;\\\" onmouseenter=\\\"require('child_process').exec('calc')\"\n\tif escapeAttributeValues(ret) {","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/filesys/tree.go#L528-L564","documentation":"Returned by `fixTreeJSONData` when `dataparser.ParseJSON(jsonData, ...)` fails to turn the (null-stripped) JSON into a tree. The error is logged and wrapped with the box+path context so the offending document is identifiable. This guards the read/repair path: a structurally invalid `.sy` cannot be normalized or fixed.","triggerScenarios":"Loading a `.sy` file whose JSON is syntactically broken or does not match the tree schema expected by `dataparser.ParseJSON`. The data has already passed through `removeUnescapedUnicodeNull`, so the failure is a real parse error, not a null-byte artifact.","commonSituations":"File corruption from a crash mid-write; partial write truncated by disk full; manual edits to a `.sy` file; incompatible version writing a newer format the parser rejects.","solutions":["Restore the document from history (`model` history view) or from a sync snapshot.","Open the `.sy` file in a JSON validator to locate the syntax error and repair it.","If reproducible, capture the file and report the parse error with the wrapped cause to diagnose the parser mismatch."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-validate JSON parses before handing to the tree parser:\nvar probe interface{}\nif err := json.Unmarshal(jsonData, &probe); err != nil {\n    return fmt.Errorf(\"pre-parse failed: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"tree, err := filesys.LoadTree(box, p, lute)\nif err != nil {\n    // err wraps the parse failure; offer history/sync restore to the user\n    logging.LogErrorf(\"load failed for %s: %s\", p, err)\n    return err\n}","preventionTips":["Never hand-edit .sy files; use the kernel APIs.","Keep history and sync enabled so corrupted docs are recoverable.","Validate imported .sy data with a JSON check before ingest."],"tags":["parse","json","corruption","tree"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}