apache/beam · error
can't generate row coder for type
Error message
can't generate row coder for type %v: must be a struct type or pointer to a struct type
What it means
rowTypeValidation rejects any reflect.Type whose kind is neither Struct nor Ptr when building a Beam row coder, erroring with "can't generate row coder for type %v: must be a struct type or pointer to a struct type". Beam's row encoding only supports (pointers to) structs; maps, slices, primitives, and interfaces cannot be encoded as rows.
Solutions
- Wrap the value in a struct type before row-coding it
- Use a pointer to the struct if needed (both Struct and Ptr kinds are accepted)
- Use a different coder (e.g. a custom coder via RegisterCoder) for non-struct types
Example fix
// before
b.Build(reflect.TypeOf("")) // string: unsupported
// after
type Payload struct { Value string }
b.Build(reflect.TypeOf(Payload{})) Defensive patterns
Strategy: validation
Validate before calling
func rowCodable(t reflect.Type) bool {
k := t.Kind()
return k == reflect.Struct || k == reflect.Ptr
} Type guard
func isStructOrPtr(t reflect.Type) bool { k := t.Kind(); return k == reflect.Struct || k == reflect.Ptr } Try / catch
if err != nil && strings.Contains(err.Error(), "must be a struct type") {
return fmt.Errorf("row coder requires a struct: %w", err)
} Prevention
- Only pass struct or *struct types to row coder builders
- Wrap named primitives in a struct before schema/row coding
- Use custom coders for non-struct types
When it happens
Trigger: Calling RowEncoderBuilder.Build() with a type like int, string, []T, map[K]V, or an interface type, which reaches rowTypeValidation and fails the kind switch.
Common situations: Passing a named primitive type (e.g. type UserId string) to the row coder builder; wiring a schema/row coder to a slice element in a DoFn; schema registry misconfiguration.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- cannot make schema for type
- decoding a *
- decoding a
- error reconciling type
- number of fields is less than byte array
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b645ef0644aa99e7.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/graph/coder/row.go:70
// schema row.
func RowEncoderForStruct(rt reflect.Type) (func(any, io.Writer) error, error) {
return defaultEnc.Build(rt)
}
// RowDecoderForStruct returns a decoding function that decodes the beam row encoding
// into the given type.
//
// Returns an error if the given type is invalid or not decodable from a beam
// schema row.
func RowDecoderForStruct(rt reflect.Type) (func(io.Reader) (any, error), error) {
return defaultDec.Build(rt)
}
func rowTypeValidation(rt reflect.Type, strictExportedFields bool) error {
switch k := rt.Kind(); k {
case reflect.Ptr, reflect.Struct:
default:
return errors.Errorf("can't generate row coder for type %v: must be a struct type or pointer to a struct type", rt)
}
// TODO exported field validation.
return nil
}
// writeRowHeader handles the field header for row encodings.
func writeRowHeader(rv reflect.Value, w io.Writer) error {
// Row/Structs are prefixed with the number of fields that are encoded in total.
if err := EncodeVarInt(int64(rv.NumField()), w); err != nil {
return err
}
// Followed by a packed bit array of the nil fields.
var curByte byte
var nils bool
var bytes = make([]byte, 0, rv.NumField()/8+1)
for i := 0; i < rv.NumField(); i++ {
shift := i % 8
if i != 0 && shift == 0 {View on GitHub (pinned to 12126d8942)