{"record":{"id":"2df84144dc5a3eca","repo":"apache/beam","slug":"logical-types-must-be-registered-with-interface-types-v-is","errorCode":null,"errorMessage":"Logical Types must be registered with interface types. %v is not an interface type.","messagePattern":"Logical Types must be registered with interface types\\. (.+?) is not an interface type\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/schema/logicaltypes.go","lineNumber":109,"sourceCode":"func (r *Registry) RegisterLogicalType(lt LogicalType) {\n\t// Validates that the storage type has known handling.\n\tst := lt.StorageType()\n\t_, err := r.reflectTypeToFieldType(st)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"LogicalType[%v] has an invalid StorageType %v: %v\", lt.ID(), st, err))\n\t}\n\tif len(lt.ID()) == 0 {\n\t\tpanic(fmt.Sprintf(\"invalid logical type, bad id: %v -> %v\", lt.GoType(), lt.StorageType()))\n\t}\n\t// TODO add duplication checks.\n\tr.logicalTypeIdentifiers[lt.GoType()] = lt.ID()\n\tr.logicalTypes[lt.ID()] = lt\n}\n\n// RegisterLogicalTypeProvider allows registration of providers for interface types.\nfunc (r *Registry) RegisterLogicalTypeProvider(rt reflect.Type, ltp LogicalTypeProvider) {\n\tif rt.Kind() != reflect.Interface {\n\t\tpanic(fmt.Sprintf(\"Logical Types must be registered with interface types. %v is not an interface type.\", rt))\n\t}\n\tif rt.NumMethod() == 0 {\n\t\tpanic(fmt.Sprintf(\"Logical Types may not be registered with empty interface types. %v has no methods.\", rt))\n\t}\n\tr.logicalTypeProviders[rt] = ltp\n\tr.logicalTypeInterfaces = append(r.logicalTypeInterfaces, rt)\n}\n\n// LogicalType is a mapping between custom Go types, and their schema equivalent storage types.\n//\n// A LogicalType is a way to define a type that can be stored in a schema field\n// using a known underlying type for storage. The storage type must be comprised of\n// known schema field types, or pre-registered LogicalTypes.\n//\n// LogicalTypes may not be mutually recursive at any level of indirection.\n// LogicalTypes must map from a Go type to a single Schema Equivalent storage type.\ntype LogicalType struct {\n\tidentifier          string","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/schema/logicaltypes.go#L91-L127","documentation":"RegisterLogicalTypeProvider maps a LogicalTypeProvider to an interface type so providers can be matched against values whose static type is an interface. Passing a non-interface reflect.Type breaks that contract, so registration panics.","triggerScenarios":"Calling Registry.RegisterLogicalTypeProvider with a concrete type (struct, pointer, basic type) as rt instead of a reflect.Type produced by reflect.TypeOf on an interface value.","commonSituations":"Accidentally registering the concrete implementation type instead of the interface; misunderstanding that the API requires interfaces with methods.","solutions":["Pass reflect.TypeOf((*MyInterface)(nil)).Elem() to obtain the interface type","Use RegisterLogicalType instead for concrete Go types","Verify rt.Kind() == reflect.Interface before calling"],"exampleFix":"// before\nschema.RegisterLogicalTypeProvider(registry, reflect.TypeOf(MyImpl{}), provider)\n// after\nvar iface MyInterface\nschema.RegisterLogicalTypeProvider(registry, reflect.TypeOf(&iface).Elem(), provider)","handlingStrategy":"validation","validationCode":"rt := reflect.TypeOf((*MyIface)(nil)).Elem()\nif rt.Kind() != reflect.Interface { return errors.New(\"must pass an interface type\") }\nr.RegisterLogicalTypeProvider(rt, provider)","typeGuard":"func isInterfaceType(rt reflect.Type) bool { return rt != nil && rt.Kind() == reflect.Interface }","tryCatchPattern":"defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"register provider: %v\", r) } }()","preventionTips":["Use reflect.TypeOf((*I)(nil)).Elem() idiom for interface types","Never pass struct/pointer types to RegisterLogicalTypeProvider","Prefer RegisterLogicalType for concrete types"],"tags":["go","apache-beam","schema","reflection","panic"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}