siyuan-note/siyuan · error
snapshot version is not a document
Error message
snapshot version is not a document
What it means
After resolving the file ID to a repo file, loadSnapshotDocVersion verifies the file's stored path ends with .sy (case-insensitive). Snapshot diffs are only supported for documents; if the snapshot object is an asset or any non-document file, this error is thrown.
Solutions
- Use the file ID of a document snapshot (path ending in .sy) from the repo file listing.
- Filter repo files by .sy path suffix before requesting version diffs.
- For asset history, use the asset history APIs instead of the document version loader.
- Re-select the history entry in the UI to get the correct document file ID.
Example fix
// before loadDocVersion(fileID_of_asset.png) -> "snapshot version is not a document" // after loadDocVersion(fileID_of_document.sy)
Defensive patterns
Strategy: validation
Validate before calling
// JS: only request diffs for .sy snapshot entries
if (!file.path.toLowerCase().endsWith(".sy")) return;
return fetchPost("/api/history/loadDocVersion", { fileID: file.id }); Type guard
function isDocSnapshot(file) { return typeof file.path === "string" && file.path.toLowerCase().endsWith(".sy"); } Try / catch
catch (e) { if (e.message === "snapshot version is not a document") { selectDocumentSnapshotInstead(); } else { throw e; } } Prevention
- Filter repo/history entries to .sy paths before diffing
- Do not pass asset file IDs to document version APIs
- When scripting, check the file path suffix before each call
When it happens
Trigger: loadDocVersion in snapshot mode with a fileID whose repo file path is not a .sy document, e.g. an asset snapshot or index file stored in the repo.
Common situations: Passing an asset's file ID where a document's file ID is expected (IDs copied from the wrong history entry); older snapshot entries for assets being diffed; a script iterating repo files and assuming all are documents.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- attribute view snapshot context is ambiguous
- Conf.Language(26)
- snapshot file ID is required
- attr must be a string or null (got %T)
- attribute view history context is ambiguous
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/edb67d03a078a7f7.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/history_diff.go:413
}
func loadSnapshotDocVersion(fileID string) (ret *loadedDocVersion, err error) {
if "" == fileID {
return nil, errors.New("snapshot file ID is required")
}
if 1 > len(Conf.Repo.Key) {
return nil, errors.New(Conf.Language(26))
}
repo, err := newRepository()
if err != nil {
return nil, err
}
file, err := repo.GetFile(fileID)
if err != nil {
return nil, err
}
if !strings.HasSuffix(strings.ToLower(file.Path), ".sy") {
return nil, errors.New("snapshot version is not a document")
}
repoPath := strings.TrimPrefix(file.Path, "/")
pathParts := strings.SplitN(repoPath, "/", 2)
data, err := repo.OpenFile(file)
if err != nil {
return nil, err
}
ciphertext := util.IsCiphertext(data)
if ciphertext {
if len(pathParts) < 2 || !ast.IsNodeIDPattern(pathParts[0]) || !IsEncryptedBox(pathParts[0]) {
return nil, errors.New("encrypted snapshot document is missing valid notebook context")
}
HoldBoxReadLock(pathParts[0])
defer ReleaseBoxReadLock(pathParts[0])
dek, unlockErr := GetDEKIfUnlocked(pathParts[0])
if unlockErr != nil {
return nil, errors.New(Conf.Language(314))
}View on GitHub (pinned to 9f775e8a12)