{"record":{"id":"bcef946210da897a","repo":"apache/beam","slug":"unable-to-convert-logicaltype-v-s-storage-type-v-for-go-type","errorCode":null,"errorMessage":"unable to convert LogicalType[%v]'s storage type %v for Go type of %v to a schema","messagePattern":"unable to convert LogicalType\\[(.+?)\\]'s storage type (.+?) for Go type of (.+?) to a schema","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/schema/schema.go","lineNumber":337,"sourceCode":"// Returns an error if the type cannot be converted to a Schema.\nfunc (r *Registry) FromType(ot reflect.Type) (*pipepb.Schema, error) {\n\tif err := r.reconcileRegistrations(); err != nil {\n\t\treturn nil, errors.Wrap(err, \"reconciling for FromType\")\n\t}\n\tif reflectx.SkipPtr(ot).Kind() != reflect.Struct {\n\t\treturn nil, errors.Errorf(\"cannot convert %v to schema. FromType only converts structs to schemas\", ot)\n\t}\n\treturn r.fromType(ot)\n}\n\nfunc (r *Registry) logicalTypeToFieldType(t reflect.Type) (*pipepb.FieldType, string, error) {\n\t// Check if a logical type was registered that matches this struct type directly\n\t// and if so, extract the schema from it for use.\n\tif lID, ok := r.logicalTypeIdentifiers[t]; ok {\n\t\tlt := r.logicalTypes[lID]\n\t\tftype, err := r.reflectTypeToFieldType(lt.StorageType())\n\t\tif err != nil {\n\t\t\treturn nil, \"\", errors.Wrapf(err, \"unable to convert LogicalType[%v]'s storage type %v for Go type of %v to a schema\", lID, lt.StorageType(), lt.GoType())\n\t\t}\n\t\treturn ftype, lID, nil\n\t}\n\tfor _, lti := range r.logicalTypeInterfaces {\n\t\tif !t.Implements(lti) {\n\t\t\tcontinue\n\t\t}\n\t\tp := r.logicalTypeProviders[lti]\n\t\tst, err := p(t)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", errors.Wrapf(err, \"unable to convert LogicalType[%v] using provider for %v schema field\", t, lti)\n\t\t}\n\t\tif st == nil {\n\t\t\tcontinue\n\t\t}\n\t\tftype, err := r.reflectTypeToFieldType(st)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", errors.Wrapf(err, \"unable to convert LogicalType[%v]'s storage type %v for Go type of %v to a schema\", \"interface\", st, t)","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/schema/schema.go#L319-L355","documentation":"Raised in Registry.logicalTypeToFieldType when a LogicalType was registered for the struct type t, but converting that logical type's StorageType() into a Beam FieldType fails. The wrap identifies the logical type ID, storage type, and Go type. It means the logical type's chosen storage representation is itself not schema-convertible.","triggerScenarios":"Calling FromType/structToSchema/reflectTypeToFieldType on a type with a directly-registered logical type (in logicalTypeIdentifiers) whose lt.StorageType() cannot be converted by reflectTypeToFieldType (e.g. storage is a func, chan, or contains nested unsupported kinds).","commonSituations":"Custom logical types registered with exotic storage types; a Beam upgrade making a previously-convertible storage type unsupported; nested logical types failing recursively.","solutions":["Inspect the wrapped error to see why the storage type fails conversion.","Change the logical type's StorageType to a schema-serializable representation (bytes, string, struct).","Re-register the logical type with a custom TypeEncoder/TypeDecoder compatible with the new storage type.","Remove the bad logical type registration if redundant."],"exampleFix":"// before\nbeam.RegisterLogicalType(beam.NewLogicalTypeWithName(\"MyT\", reflect.TypeOf(func(){}))) // bad storage\n// after\nbeam.RegisterLogicalType(beam.NewLogicalTypeWithName(\"MyT\", reflect.TypeOf(\"\"))) // string storage","handlingStrategy":"validation","validationCode":"if lID, ok := reg.HasLogicalTypeFor(reflect.TypeOf(myVal)); ok {\n    // test conversion of the storage type before pipeline build\n    if err := schemaSafe(logicalTypeStorageType(lID)); err != nil {\n        return fmt.Errorf(\"logical type %s storage not convertible: %w\", lID, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"schm, err := reg.FromType(t)\nif err != nil && strings.Contains(err.Error(), \"storage type\") {\n    return nil, fmt.Errorf(\"fix registered logical type storage: %w\", err)\n}","preventionTips":["Choose simple storage types (bytes, string, structs of primitives) for logical types.","Unit-test logical type registration plus FromType round-trips.","Pair logical types with TypeEncoder/TypeDecoder registrations.","Re-test logical types after Beam upgrades."],"tags":["go","schema","logical-type","storage-type"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}