siyuan-note/siyuan · error

parse json [%s] to tree failed: %w

Error message

parse json [%s] to tree failed: %w

What it means

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.

Source

Thrown at kernel/filesys/tree.go:546

	}
	return dst, len(dst) != n
}

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) {
	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); errors.Is(err, treenode.ErrSpecTooNew) {
		return
	}

	if treenode.UpgradeSpec(ret) {
		needFix = true
	}

	// v3.5.1 https://github.com/siyuan-note/siyuan/pull/16657 引入的问题,属性值未转义
	// v3.5.2 https://github.com/siyuan-note/siyuan/issues/16686 进行了修复,并加了订正逻辑 https://github.com/siyuan-note/siyuan/pull/16712
	// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-ff66-236v-p4fg XSS 漏洞:"title": "&\" onmouseenter=\"require('child_process').exec('calc')"
	if escapeAttributeValues(ret) {

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Restore the document from history (`model` history view) or from a sync snapshot.
  2. Open the `.sy` file in a JSON validator to locate the syntax error and repair it.
  3. If reproducible, capture the file and report the parse error with the wrapped cause to diagnose the parser mismatch.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate JSON parses before handing to the tree parser:
var probe interface{}
if err := json.Unmarshal(jsonData, &probe); err != nil {
    return fmt.Errorf("pre-parse failed: %w", err)
}

Try / catch

tree, err := filesys.LoadTree(box, p, lute)
if err != nil {
    // err wraps the parse failure; offer history/sync restore to the user
    logging.LogErrorf("load failed for %s: %s", p, err)
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/6bda6cecc88883ba. Report an issue: GitHub.