{"record":{"id":"5e7a5aea6d21836b","repo":"siyuan-note/siyuan","slug":"history-version-is-not-a-document","errorCode":null,"errorMessage":"history version is not a document","messagePattern":"history version is not a document","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/history_diff.go","lineNumber":338,"sourceCode":"\tret, err = filelock.ReadFile(absPath)\n\tif err != nil || !encrypted {\n\t\treturn\n\t}\n\tdek, err := GetDEKIfUnlocked(blockTree.BoxID)\n\tif err != nil {\n\t\treturn nil, errors.New(Conf.Language(314))\n\t}\n\tret, err = DecryptFile(blockTree.BoxID, relPath, dek, ret)\n\treturn\n}\n\nfunc loadHistoryDocVersion(historyPath string) (ret *loadedDocVersion, err error) {\n\tabsPath, err := validateHistoryPath(historyPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !strings.HasSuffix(strings.ToLower(absPath), \".sy\") {\n\t\treturn nil, errors.New(\"history version is not a document\")\n\t}\n\trelPath, err := filepath.Rel(util.HistoryDir, absPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tparts := strings.SplitN(filepath.ToSlash(relPath), \"/\", 3)\n\tdata, err := filelock.ReadFile(absPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tciphertext := util.IsCiphertext(data)\n\tif ciphertext {\n\t\tif len(parts) < 3 || !ast.IsNodeIDPattern(parts[1]) || !IsEncryptedBox(parts[1]) {\n\t\t\treturn nil, errors.New(\"encrypted document history is missing valid notebook context\")\n\t\t}\n\t\tHoldBoxReadLock(parts[1])\n\t\tdefer ReleaseBoxReadLock(parts[1])\n\t\tdek, dekErr := GetDEKIfUnlocked(parts[1])","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/history_diff.go#L320-L356","documentation":"loadHistoryDocVersion validates that the requested history path points to a .sy document file before parsing it into a document tree. If the validated path does not end with .sy (case-insensitive), the loader refuses because history diff only works on document snapshots, not assets or other history artifacts.","triggerScenarios":"Calling the load-history-doc-version path (via loadDocVersion) with a historyPath that points to a non-document file under history/, e.g. an asset, .json index, or directory entry whose name lacks a .sy suffix.","commonSituations":"A caller passes a history record for an asset file instead of a document; stale UI links to a renamed/removed .sy; manually constructed historyPath from a history listing that includes non-document entries.","solutions":["Pass a historyPath that points to a document snapshot ending in .sy (e.g. history/<timestamp>/<boxID>/<docID>.sy).","Use the history listing API to obtain valid document history paths instead of hand-building them.","If the file was renamed or removed, pick the correct timestamp entry that still contains the .sy document.","For asset history, use the appropriate asset-history API, not the document version loader."],"exampleFix":"// before\nloadDocVersion(\"history/20240101120000/20240101120000-abc/assets/foo.png\")\n// after\nloadDocVersion(\"history/20240101120000/20240101120000-abc/20240101150000-def.sy\")","handlingStrategy":"validation","validationCode":"// Go: validate the history path points to a .sy document before calling\nif !strings.EqualFold(filepath.Ext(historyPath), \".sy\") {\n    return errors.New(\"refusing to diff non-document history entry\")\n}","typeGuard":null,"tryCatchPattern":"catch (e) { if (e.message === \"history version is not a document\") { pickDocumentHistoryEntry(); } else { throw e; } }","preventionTips":["Always obtain historyPath from the history listing API, never hand-build it","Filter history entries to .sy files before requesting version diffs","Do not rename or move files inside the history directory"],"tags":["history","invalid-path","document"],"backgroundTag":"incompatible-source-type","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"}