{"record":{"id":"a7426a6148766793","repo":"siyuan-note/siyuan","slug":"document-versions-do-not-belong-to-the-same-docume","errorCode":null,"errorMessage":"document versions do not belong to the same document","messagePattern":"document versions do not belong to the same document","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/history_diff.go","lineNumber":163,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"unsupported document version type [%s]\", ref.Type)\n\t}\n}\n\n// DiffDocVersions 比较同一文档的两个版本，并返回带临时差异标记的只读块 DOM。\nfunc DiffDocVersions(leftRef, rightRef *DocVersionRef) (ret *DocVersionDiffResult, err error) {\n\tif (nil != leftRef && docVersionCurrent == leftRef.Type) || (nil != rightRef && docVersionCurrent == rightRef.Type) {\n\t\tFlushTxQueue()\n\t}\n\tleft, err := loadDocVersion(leftRef)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tright, err := loadDocVersion(rightRef)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif \"\" != left.rootID && \"\" != right.rootID && left.rootID != right.rootID {\n\t\treturn nil, errors.New(\"document versions do not belong to the same document\")\n\t}\n\n\tret = &DocVersionDiffResult{\n\t\tDifferences:   []*DocVersionDifference{},\n\t\tLarge:         left.large || right.large,\n\t\tTitleModified: left.title != right.title,\n\t}\n\tif nil == left.tree || nil == right.tree {\n\t\tret.Fallback = true\n\t\tret.Message = docVersionFallbackMessage(left, right)\n\t\tret.TitleModified = false\n\t\tret.Left = renderFallbackDocVersion(left)\n\t\tret.Right = renderFallbackDocVersion(right)\n\t\treturn\n\t}\n\tif ret.TitleModified {\n\t\tret.Differences = append(ret.Differences, &DocVersionDifference{\n\t\t\tID:       left.tree.Root.ID,","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/history_diff.go#L145-L181","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["On the client, only enable the diff action when both selected versions share the same rootID (the history list already carries it).","Before calling DiffDocVersions, fetch each version's rootID and short-circuit with a user-facing message if they differ.","If comparing across a rename is intended, look up the current rootID via treenode.GetBlockTree and map old IDs to new ones before diffing."],"exampleFix":"// before\ndiff, err := DiffDocVersions(leftRef, rightRef)\n\n// after\nif leftRef.RootID() != \"\" && rightRef.RootID() != \"\" && leftRef.RootID() != rightRef.RootID() {\n    return nil, errors.New(\"document versions do not belong to the same document\")\n}\ndiff, err := DiffDocVersions(leftRef, rightRef)","handlingStrategy":"validation","validationCode":"// fetch each version's rootID first (history list / block tree), then:\nif leftRootID != \"\" && rightRootID != \"\" && leftRootID != rightRootID {\n    return errors.New(\"document versions do not belong to the same document\")\n}\ndiff, err := DiffDocVersions(leftRef, rightRef)","typeGuard":"// sameDoc reports whether two DocVersionRefs point at the same root document.\nfunc sameDoc(a, b *DocVersionRef) bool {\n    if a == nil || b == nil { return false }\n    return a.rootID() != \"\" && a.rootID() == b.rootID()\n}","tryCatchPattern":"diff, err := DiffDocVersions(left, right)\nif err != nil && strings.Contains(err.Error(), \"do not belong to the same document\") {\n    // surface a user-facing mismatch message instead of a generic error\n}","preventionTips":["On the client, only enable diff when both selected rows share a rootID.","When diffing across a rename, map old rootIDs to the current one first.","Tag history entries with their rootID in the UI so users can see mismatches before submitting."],"tags":["history-diff","validation","document-model"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}