siyuan-note/siyuan · error

document versions do not belong to the same document

Error message

document versions do not belong to the same document

What it means

Returned by DiffDocVersions (history_diff.go:163) when both loaded versions expose a non-empty rootID and those rootIDs differ. The diff engine only compares two snapshots of the same document; cross-document diffing is not supported. The check runs after loadDocVersion succeeds, so both versions resolved but belong to different trees.

Source

Thrown at kernel/model/history_diff.go:163

		return "", fmt.Errorf("unsupported document version type [%s]", ref.Type)
	}
}

// DiffDocVersions 比较同一文档的两个版本,并返回带临时差异标记的只读块 DOM。
func DiffDocVersions(leftRef, rightRef *DocVersionRef) (ret *DocVersionDiffResult, err error) {
	if (nil != leftRef && docVersionCurrent == leftRef.Type) || (nil != rightRef && docVersionCurrent == rightRef.Type) {
		FlushTxQueue()
	}
	left, err := loadDocVersion(leftRef)
	if err != nil {
		return nil, err
	}
	right, err := loadDocVersion(rightRef)
	if err != nil {
		return nil, err
	}
	if "" != left.rootID && "" != right.rootID && left.rootID != right.rootID {
		return nil, errors.New("document versions do not belong to the same document")
	}

	ret = &DocVersionDiffResult{
		Differences:   []*DocVersionDifference{},
		Large:         left.large || right.large,
		TitleModified: left.title != right.title,
	}
	if nil == left.tree || nil == right.tree {
		ret.Fallback = true
		ret.Message = docVersionFallbackMessage(left, right)
		ret.TitleModified = false
		ret.Left = renderFallbackDocVersion(left)
		ret.Right = renderFallbackDocVersion(right)
		return
	}
	if ret.TitleModified {
		ret.Differences = append(ret.Differences, &DocVersionDifference{
			ID:       left.tree.Root.ID,

View on GitHub (pinned to 251596fc0d)

Solutions

  1. On the client, only enable the diff action when both selected versions share the same rootID (the history list already carries it).
  2. Before calling DiffDocVersions, fetch each version's rootID and short-circuit with a user-facing message if they differ.
  3. If comparing across a rename is intended, look up the current rootID via treenode.GetBlockTree and map old IDs to new ones before diffing.

Example fix

// before
diff, err := DiffDocVersions(leftRef, rightRef)

// after
if leftRef.RootID() != "" && rightRef.RootID() != "" && leftRef.RootID() != rightRef.RootID() {
    return nil, errors.New("document versions do not belong to the same document")
}
diff, err := DiffDocVersions(leftRef, rightRef)
Defensive patterns

Strategy: validation

Validate before calling

// fetch each version's rootID first (history list / block tree), then:
if leftRootID != "" && rightRootID != "" && leftRootID != rightRootID {
    return errors.New("document versions do not belong to the same document")
}
diff, err := DiffDocVersions(leftRef, rightRef)

Type guard

// sameDoc reports whether two DocVersionRefs point at the same root document.
func sameDoc(a, b *DocVersionRef) bool {
    if a == nil || b == nil { return false }
    return a.rootID() != "" && a.rootID() == b.rootID()
}

Try / catch

diff, err := DiffDocVersions(left, right)
if err != nil && strings.Contains(err.Error(), "do not belong to the same document") {
    // surface a user-facing mismatch message instead of a generic error
}

Prevention

When it happens

Trigger: POST /api/history/diffDocVersions where left is a snapshot of doc A and right is a snapshot/current of doc B; mixing a history entry of one doc with the current version of another; frontend bug that pairs the wrong history rows in the diff dialog.

Common situations: User selects two history entries from different documents in the history panel; a renamed/moved doc whose rootID changed; copy-paste of a history path from a different doc.

Related errors


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