{"record":{"id":"9a07f9fcb0218dea","repo":"siyuan-note/siyuan","slug":"invalid-document-json-s","errorCode":null,"errorMessage":"invalid document JSON: %s","messagePattern":"invalid document JSON: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/asset_relink.go","lineNumber":170,"sourceCode":"\t\t\tif !strings.HasSuffix(entry.Name(), \".sy\") {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif err := p.observe(absPath); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tp.reportProgress(absPath)\n\t\t\tdata, readErr := filelock.ReadFile(absPath)\n\t\t\tif readErr != nil {\n\t\t\t\treturn readErr\n\t\t\t}\n\t\t\tif util.IsCiphertext(data) {\n\t\t\t\treturn fmt.Errorf(\"encrypted document in ordinary notebook: %s\", absPath)\n\t\t\t}\n\t\t\tif readErr = treenode.CheckSpecJSON(data); readErr != nil {\n\t\t\t\treturn readErr\n\t\t\t}\n\t\t\tif !json.Valid(data) {\n\t\t\t\treturn fmt.Errorf(\"invalid document JSON: %s\", absPath)\n\t\t\t}\n\t\t\tvar header struct {\n\t\t\t\tID         string `json:\"ID\"`\n\t\t\t\tProperties struct {\n\t\t\t\t\tTitle string `json:\"title\"`\n\t\t\t\t} `json:\"Properties\"`\n\t\t\t}\n\t\t\tif readErr = json.Unmarshal(data, &header); readErr != nil {\n\t\t\t\treturn readErr\n\t\t\t}\n\t\t\ttitles[header.ID] = header.Properties.Title\n\t\t\tif !p.mayContainReferences(data) && !bytes.Contains(data, []byte(\"NodeAttributeView\")) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tp.parsedDocuments++\n\t\t\ttree, readErr := dataparser.ParseJSONWithoutFix(data, luteEngine.ParseOptions)\n\t\t\tif readErr != nil || tree == nil || tree.Root == nil {\n\t\t\t\treturn fmt.Errorf(\"cannot parse document %s: %v\", absPath, readErr)","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/asset_relink.go#L152-L188","documentation":"The scan reads each .sy document and validates that its content is well-formed JSON via json.Valid(data) (after the spec check). If the bytes are not valid JSON, the document is corrupt or not a SiYuan document, and the scan aborts with the absolute path rather than silently skipping a potentially referenced document.","triggerScenarios":"A .sy file whose contents are truncated (interrupted write/pull), corrupted by an external editor or failed sync merge, binary garbage, or an empty file; encountered by FindAssetReferences/RelinkAsset during notebook traversal.","commonSituations":"Disk-full or power loss during a document save; git merge conflicts left conflict markers inside a .sy file; manual editing of .sy files with a text editor saving invalid JSON; a third-party tool writing partial JSON.","solutions":["Inspect the reported .sy file: repair or restore it from a snapshot/history backup or file history.","If the document is unwanted, remove it from the notebook so the scan can proceed.","Re-run relinking with dryRun=true after fixing to confirm the whole tree parses.","Restore the workspace from sync or local history if multiple documents are corrupted.","Never hand-edit .sy JSON without validating afterward (e.g. with a JSON linter)."],"exampleFix":"// before (terminal)\ncat data/notebooks/xxx/20240101120000-abc.sy  # truncated JSON\n// after (terminal)\ncp .siyuan/history/.../20240101120000-abc.sy data/notebooks/xxx/20240101120000-abc.sy","handlingStrategy":"try-catch","validationCode":"data, _ := filelock.ReadFile(syPath)\nif !json.Valid(data) {\n    return fmt.Errorf(\"corrupt document: %s\", syPath)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.HasPrefix(err.Error(), \"invalid document JSON\") {\n    // restore the file from history/snapshot before retrying\n}","preventionTips":["Never hand-edit .sy files without JSON validation","Ensure clean shutdown/backup to avoid truncated writes","Validate .sy files after restore operations"],"tags":["json","corruption","asset-relink"],"backgroundTag":"json-parse-error","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}