{"record":{"id":"e47dd040d62901a0","repo":"apache/beam","slug":"unsupported-type-s-mapper","errorCode":null,"errorMessage":"unsupported type %s","messagePattern":"unsupported type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/io/databaseio/mapper.go","lineNumber":40,"sourceCode":"\t\"reflect\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/apache/beam/sdks/v2/go/pkg/beam/internal/errors\"\n)\n\n// rowMapper represents a record mapper\ntype rowMapper func(value reflect.Value) ([]any, error)\n\n// newQueryMapper creates a new record mapped\nfunc newQueryMapper(columns []string, columnTypes []*sql.ColumnType, recordType reflect.Type) (rowMapper, error) {\n\tval := reflect.New(recordType).Interface()\n\tif _, isLoader := val.(MapLoader); isLoader {\n\t\treturn newQueryLoaderMapper(columns, columnTypes)\n\t} else if recordType.Kind() == reflect.Struct {\n\t\treturn newQueryStructMapper(columns, recordType)\n\t}\n\treturn nil, errors.Errorf(\"unsupported type %s\", recordType)\n}\n\n// newQueryStructMapper creates a new record mapper for supplied struct type\nfunc newQueryStructMapper(columns []string, recordType reflect.Type) (rowMapper, error) {\n\tmappedFieldIndex, err := mapFields(columns, recordType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar record = make([]any, recordType.NumField())\n\tvar mapper = func(value reflect.Value) ([]any, error) {\n\t\tvalue = value.Elem() //T = *T\n\t\tfor i, fieldIndex := range mappedFieldIndex {\n\t\t\trecord[i] = value.Field(fieldIndex).Addr().Interface()\n\t\t}\n\t\treturn record, nil\n\t}\n\treturn mapper, nil\n}","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/databaseio/mapper.go#L22-L58","documentation":"Raised by newQueryMapper when the record type passed for reading rows is neither a MapLoader implementation nor a Go struct. The read path supports only structs (mapped field-by-field) or types implementing MapLoader (self-scanning); anything else — e.g. a plain int, string, map, or interface — cannot be mapped, so the mapper creation fails eagerly before any row is read.","triggerScenarios":"Calling databaseio.Read with a generic type parameter (or reflection type) that is not a struct and does not implement databaseio.MapLoader — for example Read[s] with T = string, []byte, map[string]any, or a pointer-to-non-struct type.","commonSituations":"Developers trying to read rows into primitives or maps for convenience; passing interface types; using generics with T inferred as a non-struct type; refactoring that changed the element type from a struct to a slice or alias.","solutions":["Change the read element type to a struct whose exported fields match the query's columns.","Alternatively implement the databaseio.MapLoader interface on your type so it can load values itself.","If you need dynamic columns, read into a struct with the needed fields instead of a map."],"exampleFix":"// before\ncol := databaseio.Read[s](scope, db, \"SELECT name, age FROM users\") // T = string -> unsupported\n// after\ntype User struct { Name string; Age int }\ncol := databaseio.Read[User](scope, db, \"SELECT name, age FROM users\")","handlingStrategy":"type-guard","validationCode":"// compile-time / pre-call check for the Read type parameter\nfunc assertReadableType[T any]() error {\n    var zero T\n    t := reflect.TypeOf(&zero).Elem()\n    if t.Kind() == reflect.Struct { return nil }\n    if _, ok := any(&zero).(databaseio.MapLoader); ok { return nil }\n    return fmt.Errorf(\"type %s must be a struct or implement databaseio.MapLoader\", t)\n}","typeGuard":"func isReadableType[T any]() bool {\n    var zero T\n    t := reflect.TypeOf(&zero).Elem()\n    return t.Kind() == reflect.Struct || func() bool { _, ok := any(&zero).(databaseio.MapLoader); return ok }()\n}","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"unsupported type\") {\n        return fmt.Errorf(\"%w; use a struct type or implement databaseio.MapLoader\", err)\n    }\n    return err\n}","preventionTips":["Always parameterize databaseio.Read with a struct type whose fields match the query columns.","Implement databaseio.MapLoader for custom scanning behavior on non-struct types.","Add a compile-time assertion (var _ = assertReadableType[MyType]) in package tests.","Avoid maps, slices, or primitives as read element types — they are not supported."],"tags":["reflection","unsupported-type","generics","beam-io"],"backgroundTag":"unsupported-operation","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"}