siyuan-note/siyuan · error

unsupported document version type [%s]

Error message

unsupported document version type [%s]

What it means

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.

Source

Thrown at kernel/model/history_diff.go:145

		}
		if IsEncryptedBox(blockTree.BoxID) {
			return blockTree.BoxID, nil
		}
		return "", nil
	case docVersionHistory:
		absPath, err := validateHistoryPath(ref.Path)
		if err != nil {
			return "", err
		}
		boxID := ExtractBoxIDFromHistoryPath(absPath)
		if IsEncryptedBox(boxID) {
			return boxID, nil
		}
		return "", nil
	case docVersionSnapshot:
		return ResolveRepoFileBoxID(ref.ID)
	default:
		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")

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Only assign DocVersionRef.Type from the package's exported constants (docVersionCurrent/docVersionHistory/docVersionSnapshot)
  2. Validate the type value client-side before the call and reject unknown values early
  3. Check that the caller and the kernel are built from compatible versions of the model package
  4. If deserializing, map/validate the wire value against the known enum before constructing the struct

Example fix

// before
ref := &DocVersionRef{Type: 99, ID: docID}
// after
ref := &DocVersionRef{Type: docVersionCurrent, ID: docID}
Defensive patterns

Strategy: validation

Validate before calling

switch ref.Type {
case model.DocVersionCurrent, model.DocVersionHistory, model.DocVersionSnapshot:
    // ok
default:
    return fmt.Errorf("unknown doc version type %v", ref.Type)
}

Type guard

func knownVersionType(t model.DocVersionType) bool {
    switch t {
    case model.DocVersionCurrent, model.DocVersionHistory, model.DocVersionSnapshot:
        return true
    }
    return false
}

Try / catch

if _, err := ResolveDocVersionBoxID(ref); err != nil {
    var unsupportedErr bool
    if strings.HasPrefix(err.Error(), "unsupported document version type") {
        unsupportedErr = true
    }
    if unsupportedErr {
        return userFacingError("this version type is not supported by your kernel version")
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/3ec5aa1c849aa5b9. Report an issue: GitHub.