siyuan-note/siyuan · error
cannot parse document
Error message
cannot parse document %s: %v
What it means
After preliminary content checks, the document is parsed with dataparser.ParseJSONWithoutFix. If parsing fails or yields a nil tree/root, the scan reports 'cannot parse document' wrapping the underlying error. Unlike the raw json.Valid check, this catches structurally valid JSON that is not a valid document tree.
Solutions
- Read the wrapped %v cause to see why parsing failed and fix the document accordingly.
- Restore the document from history or sync snapshots; if it is disposable, delete it.
- Open and resave the document in the SiYuan app so the normal parser can repair it, then retry the relink.
- If it stems from a format-version mismatch, upgrade/downgrade SiYuan to a compatible version before scanning.
Defensive patterns
Strategy: try-catch
Try / catch
if err != nil && strings.HasPrefix(err.Error(), "cannot parse document") {
// inspect wrapped cause, restore or repair the document
} Prevention
- Use the app to create/mutate documents rather than external scripts
- Keep SiYuan versions compatible with your data format
- Restore corrupt documents from snapshots promptly
When it happens
Trigger: A .sy file with valid JSON but a malformed document structure (missing root node, wrong node kinds) that ParseJSONWithoutFix cannot build into a tree; tree or tree.Root is nil after parsing; encountered during the relink notebook scan.
Common situations: Documents produced or mutated by third-party scripts that wrote plausible-but-invalid JSON; forward/backward format incompatibility after a version change; corruption that preserves JSON validity but breaks the AST invariants.
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
- asset escapes its directory
- asset must be a regular file
- attribute view rich text style entity was not restored
- attribute view rich text tree is missing
- code block has no code node
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/ee38d4f754aef503.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/asset_relink.go:188
return fmt.Errorf("invalid document JSON: %s", absPath)
}
var header struct {
ID string `json:"ID"`
Properties struct {
Title string `json:"title"`
} `json:"Properties"`
}
if readErr = json.Unmarshal(data, &header); readErr != nil {
return readErr
}
titles[header.ID] = header.Properties.Title
if !p.mayContainReferences(data) && !bytes.Contains(data, []byte("NodeAttributeView")) {
return nil
}
p.parsedDocuments++
tree, readErr := dataparser.ParseJSONWithoutFix(data, luteEngine.ParseOptions)
if readErr != nil || tree == nil || tree.Root == nil {
return fmt.Errorf("cannot parse document %s: %v", absPath, readErr)
}
rel, _ := filepath.Rel(boxDir, absPath)
tree.Box, tree.Path = boxID, "/"+filepath.ToSlash(rel)
tree.Root.Box, tree.Root.Path = tree.Box, tree.Path
tree.HPath = "/" + tree.Root.IALAttr("title")
if readErr = filesys.NormalizeTreeForRead(tree); readErr != nil {
return readErr
}
if tree.Root.ID != strings.TrimSuffix(entry.Name(), ".sy") {
return fmt.Errorf("document ID does not match path: %s", absPath)
}
titles[tree.Root.ID] = tree.Root.IALAttr("title")
before := len(p.result.References)
p.tree(tree, apicontract.AssetReference{Notebook: boxID, RootID: tree.Root.ID, Path: tree.Path})
retain := false
if len(p.result.References) > before {
p.files = append(p.files, &assetRelinkFile{path: absPath, before: data, tree: tree, items: p.referenceItems(before)})
retain = trueView on GitHub (pinned to 9f775e8a12)