{"record":{"id":"b645ef0644aa99e7","repo":"apache/beam","slug":"can-t-generate-row-coder-for-type-v-must-be-a-struct-type-or","errorCode":null,"errorMessage":"can't generate row coder for type %v: must be a struct type or pointer to a struct type","messagePattern":"can't generate row coder for type (.+?): must be a struct type or pointer to a struct type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/coder/row.go","lineNumber":70,"sourceCode":"// schema row.\nfunc RowEncoderForStruct(rt reflect.Type) (func(any, io.Writer) error, error) {\n\treturn defaultEnc.Build(rt)\n}\n\n// RowDecoderForStruct returns a decoding function that decodes the beam row encoding\n// into the given type.\n//\n// Returns an error if the given type is invalid or not decodable from a beam\n// schema row.\nfunc RowDecoderForStruct(rt reflect.Type) (func(io.Reader) (any, error), error) {\n\treturn defaultDec.Build(rt)\n}\n\nfunc rowTypeValidation(rt reflect.Type, strictExportedFields bool) error {\n\tswitch k := rt.Kind(); k {\n\tcase reflect.Ptr, reflect.Struct:\n\tdefault:\n\t\treturn errors.Errorf(\"can't generate row coder for type %v: must be a struct type or pointer to a struct type\", rt)\n\t}\n\t// TODO exported field validation.\n\treturn nil\n}\n\n// writeRowHeader handles the field header for row encodings.\nfunc writeRowHeader(rv reflect.Value, w io.Writer) error {\n\t// Row/Structs are prefixed with the number of fields that are encoded in total.\n\tif err := EncodeVarInt(int64(rv.NumField()), w); err != nil {\n\t\treturn err\n\t}\n\t// Followed by a packed bit array of the nil fields.\n\tvar curByte byte\n\tvar nils bool\n\tvar bytes = make([]byte, 0, rv.NumField()/8+1)\n\tfor i := 0; i < rv.NumField(); i++ {\n\t\tshift := i % 8\n\t\tif i != 0 && shift == 0 {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/coder/row.go#L52-L88","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nb.Build(reflect.TypeOf(\"\")) // string: unsupported\n// after\ntype Payload struct { Value string }\nb.Build(reflect.TypeOf(Payload{}))","handlingStrategy":"validation","validationCode":"func rowCodable(t reflect.Type) bool {\n    k := t.Kind()\n    return k == reflect.Struct || k == reflect.Ptr\n}","typeGuard":"func isStructOrPtr(t reflect.Type) bool { k := t.Kind(); return k == reflect.Struct || k == reflect.Ptr }","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"must be a struct type\") {\n    return fmt.Errorf(\"row coder requires a struct: %w\", err)\n}","preventionTips":["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"],"tags":["go","beam","row-coder","schema"],"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"}