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

  1. Inspect the underlying file/snapshot on disk to confirm it is non-empty and valid JSON.
  2. 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.
  3. 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

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


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/3ffb2db4207fdaae. Report an issue: GitHub.