{"record":{"id":"3ec5aa1c849aa5b9","repo":"siyuan-note/siyuan","slug":"unsupported-document-version-type-s","errorCode":null,"errorMessage":"unsupported document version type [%s]","messagePattern":"unsupported document version type \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/history_diff.go","lineNumber":145,"sourceCode":"\t\t}\n\t\tif IsEncryptedBox(blockTree.BoxID) {\n\t\t\treturn blockTree.BoxID, nil\n\t\t}\n\t\treturn \"\", nil\n\tcase docVersionHistory:\n\t\tabsPath, err := validateHistoryPath(ref.Path)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tboxID := ExtractBoxIDFromHistoryPath(absPath)\n\t\tif IsEncryptedBox(boxID) {\n\t\t\treturn boxID, nil\n\t\t}\n\t\treturn \"\", nil\n\tcase docVersionSnapshot:\n\t\treturn ResolveRepoFileBoxID(ref.ID)\n\tdefault:\n\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\")","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/history_diff.go#L127-L163","documentation":"DocVersionRef.Type is a closed enum (docVersionCurrent, docVersionHistory, docVersionSnapshot). ResolveDocVersionBoxID handles each known type and uses the default branch to reject any other value, formatting the offending value into the message with fmt.Errorf.","triggerScenarios":"Calling ResolveDocVersionBoxID with a DocVersionRef whose Type field was set to an undefined constant, zero value, or a type imported from a different version of the package.","commonSituations":"Plugin/API code hand-building the enum instead of using the exported constants; JSON/protobuf deserialization mapping an unknown wire value to an out-of-range integer; package version mismatch where a newer type value reaches older kernel code.","solutions":["Only assign DocVersionRef.Type from the package's exported constants (docVersionCurrent/docVersionHistory/docVersionSnapshot)","Validate the type value client-side before the call and reject unknown values early","Check that the caller and the kernel are built from compatible versions of the model package","If deserializing, map/validate the wire value against the known enum before constructing the struct"],"exampleFix":"// before\nref := &DocVersionRef{Type: 99, ID: docID}\n// after\nref := &DocVersionRef{Type: docVersionCurrent, ID: docID}","handlingStrategy":"validation","validationCode":"switch ref.Type {\ncase model.DocVersionCurrent, model.DocVersionHistory, model.DocVersionSnapshot:\n    // ok\ndefault:\n    return fmt.Errorf(\"unknown doc version type %v\", ref.Type)\n}","typeGuard":"func knownVersionType(t model.DocVersionType) bool {\n    switch t {\n    case model.DocVersionCurrent, model.DocVersionHistory, model.DocVersionSnapshot:\n        return true\n    }\n    return false\n}","tryCatchPattern":"if _, err := ResolveDocVersionBoxID(ref); err != nil {\n    var unsupportedErr bool\n    if strings.HasPrefix(err.Error(), \"unsupported document version type\") {\n        unsupportedErr = true\n    }\n    if unsupportedErr {\n        return userFacingError(\"this version type is not supported by your kernel version\")\n    }\n    return err\n}","preventionTips":["Always assign Type from exported constants, never raw literals","Validate enum values after deserialization from JSON/protobuf","Keep client and kernel on compatible package versions","Cover all enum cases in switch statements so new values fail at compile time"],"tags":["go","enum","document-version","diff"],"backgroundTag":"invalid-enum-value","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}