{"record":{"id":"3ffb2db4207fdaae","repo":"siyuan-note/siyuan","slug":"document-version-is-empty","errorCode":null,"errorMessage":"document version is empty","messagePattern":"document version is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/history_diff.go","lineNumber":270,"sourceCode":"\t}\n\tswitch ref.Type {\n\tcase docVersionCurrent:\n\t\tif !ast.IsNodeIDPattern(ref.ID) {\n\t\t\treturn nil, errors.New(\"current document ID is invalid\")\n\t\t}\n\t\tret, err = loadCurrentDocVersion(ref.ID)\n\tcase docVersionHistory:\n\t\tret, err = loadHistoryDocVersion(ref.Path)\n\tcase docVersionSnapshot:\n\t\tret, err = loadSnapshotDocVersion(ref.ID)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported document version type [%s]\", ref.Type)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif nil == ret || (nil == ret.tree && 0 == len(ret.raw)) || (nil != ret.tree && nil == ret.tree.Root) {\n\t\treturn nil, errors.New(\"document version is empty\")\n\t}\n\tif nil != ret.tree && \"\" == ret.rootID {\n\t\tret.rootID = ret.tree.Root.ID\n\t}\n\tif nil != ret.tree && \"\" == ret.title {\n\t\tret.title = ret.tree.Root.IALAttr(\"title\")\n\t}\n\tif \"\" == ret.title {\n\t\tret.title = ret.rootID\n\t}\n\treturn\n}\n\nfunc loadCurrentDocVersion(id string) (ret *loadedDocVersion, err error) {\n\tblockTree := treenode.GetBlockTree(id)\n\tif nil == blockTree {\n\t\treturn nil, ErrTreeNotFound\n\t}","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/history_diff.go#L252-L288","documentation":"After the type dispatch, loadDocVersion sanity-checks the loaded version: it must produce a parseable tree with a Root, or raw content. If the loader returned an empty result (nil tree, no raw bytes, or tree without Root), this error signals the stored version is empty or unparseable - the version data itself is unusable.","triggerScenarios":"loadCurrentDocVersion / loadHistoryDocVersion / loadSnapshotDocVersion returned a loadedDocVersion with nil tree, empty raw, or tree.Root == nil - e.g. a zero-byte or truncated .sy history file, a corrupt snapshot entry, or a history record whose content failed to parse into a tree.","commonSituations":"History file truncated by disk-full during a previous write; snapshot corrupted after interrupted sync/backup restore; hand-edited or partially copied history directory; ancient format version the parser reads as empty.","solutions":["Inspect the history/snapshot file referenced by the ref - if it is 0 bytes or truncated, discard that version and pick another.","Restore the affected history data from sync/backup snapshot.","Re-create the history entry by editing and re-saving the document (generates a fresh snapshot).","Check kernel logs for parse errors just before this message to identify the corrupt source.","Do not hand-edit files under data/history/; let the kernel manage them."],"exampleFix":"// caller-side guard\nloaded, err := loadHistoryDocVersion(ref.Path)\nif err != nil {\n    logging.LogErrorf(\"skip unusable doc version [%s]: %v\", ref.Path, err)\n    return nil, fmt.Errorf(\"history version [%s] is corrupt, choose another version\", ref.Path)\n}","handlingStrategy":"try-catch","validationCode":"info, err := os.Stat(historyFile)\nif err != nil || info.Size() == 0 {\n    return fmt.Errorf(\"history version file %s is missing or empty; pick another version\", historyFile)\n}","typeGuard":null,"tryCatchPattern":"diff, err := model.DiffDocVersions(leftRef, rightRef)\nif err != nil && strings.Contains(err.Error(), \"document version is empty\") {\n    return fmt.Errorf(\"a selected version is corrupt/empty; choose different versions or restore from backup\")\n}","preventionTips":["Never hand-edit data/history files","Ensure disks are not full during history writes","Restore corrupted history from sync/backup snapshots","Regenerate history by re-saving the document"],"tags":["data-corruption","document-history","diff","empty-content"],"backgroundTag":"empty-required-field","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"}