siyuan-note/siyuan · error
document version is empty
Error message
document version is empty
What it means
Returned by loadDocVersion (history_diff.go:270) when the loader produced no usable content: ret is nil, or both ret.tree and ret.raw are empty, or ret.tree has a nil Root. It fires after the type-specific loader succeeds, meaning the file/snapshot was found but is structurally empty or unparseable in a way the loader represented as an empty struct. Distinct from a parse error (which is stored on loadedDocVersion.parseErr and still returns a non-nil ret).
Source
Thrown at kernel/model/history_diff.go:270
}
switch ref.Type {
case docVersionCurrent:
if !ast.IsNodeIDPattern(ref.ID) {
return nil, errors.New("current document ID is invalid")
}
ret, err = loadCurrentDocVersion(ref.ID)
case docVersionHistory:
ret, err = loadHistoryDocVersion(ref.Path)
case docVersionSnapshot:
ret, err = loadSnapshotDocVersion(ref.ID)
default:
return nil, fmt.Errorf("unsupported document version type [%s]", ref.Type)
}
if err != nil {
return nil, err
}
if nil == ret || (nil == ret.tree && 0 == len(ret.raw)) || (nil != ret.tree && nil == ret.tree.Root) {
return nil, errors.New("document version is empty")
}
if nil != ret.tree && "" == ret.rootID {
ret.rootID = ret.tree.Root.ID
}
if nil != ret.tree && "" == ret.title {
ret.title = ret.tree.Root.IALAttr("title")
}
if "" == ret.title {
ret.title = ret.rootID
}
return
}
func loadCurrentDocVersion(id string) (ret *loadedDocVersion, err error) {
blockTree := treenode.GetBlockTree(id)
if nil == blockTree {
return nil, ErrTreeNotFound
}View on GitHub (pinned to 251596fc0d)
Solutions
- Inspect the underlying file/snapshot on disk to confirm it is non-empty and valid JSON.
- If the file is legitimately empty (e.g. an empty doc snapshot), have the loader return a parseErr-style fallback so DiffDocVersions uses the fallback path instead of failing.
- Run a workspace integrity check / re-index to regenerate corrupted history entries.
Defensive patterns
Strategy: try-catch
Validate before calling
// Before diffing, confirm the underlying file/snapshot is non-empty.
info, err := os.Stat(absPath)
if err != nil || info.Size() == 0 {
return errors.New("document version is empty")
} Try / catch
diff, err := DiffDocVersions(left, right)
if err != nil && strings.Contains(err.Error(), "document version is empty") {
// inspect the source file/snapshot on disk; offer to regenerate history
} Prevention
- Run workspace integrity checks periodically to detect zero-byte .sy files.
- If a loader legitimately returns empty content, populate parseErr so DiffDocVersions takes the fallback path.
- Log the absPath/repo fileID alongside this error for faster root-cause.
When it happens
Trigger: A history .sy file that is zero bytes; a snapshot whose repo blob decrypted to empty; a tree whose root node was stripped during parse; a code path that returns &loadedDocVersion{} without populating tree or raw.
Common situations: Corrupted history file from a crash mid-write; a snapshot taken of an empty doc that was later deleted; manual editing of .sy files; race between doc deletion and history generation.
Related errors
- document version is required
- current document ID is invalid
- document versions do not belong to the same document
- history version is not a document
- snapshot file ID is required
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/3ffb2db4207fdaae.
Report an issue: GitHub.