apache/beam · error
bad element type
Error message
bad element type
What it means
encodeType converts a Go reflect.Type to its protobuf Type representation. The 'bad element type' wrap with 'encoding slice' means the slice's element type itself failed to encode - encodeType recursion failed on t.Elem(). The failure propagates from deeper in the type tree (e.g. a slice of maps, which is explicitly unencodable).
Solutions
- Inspect the full wrapped error context chain to find the deepest failing type in the slice element tree.
- Replace map/array elements with slices or structs of exported fields.
- Wrap unencodable element types as struct fields (beam issue 23101 workaround).
- Register custom element types in the Beam type registry for EXTERNAL encoding.
Example fix
// before
func f(xs []map[string]int) { ... }
// after
type Entry struct { K string; V int }
func f(xs []Entry) { ... } Defensive patterns
Strategy: validation
Validate before calling
elm := reflect.TypeOf(xs).Elem()
if err := isEncodableType(elm); err != nil {
return fmt.Errorf("slice element %v unencodable: %w", elm, err)
} Type guard
func encodableSlice(s any) bool { t := reflect.TypeOf(s); return t.Kind() == reflect.Slice && isEncodableType(t.Elem()) == nil } Try / catch
if err := isEncodableType(reflect.TypeOf(xs)); err != nil {
return fmt.Errorf("fix element type before export: %w", err)
} Prevention
- Avoid slices of maps/arrays as element types
- Keep slice elements to primitives, strings, and exported-field structs
- Read the wrapped 'encoding slice %v' context to identify the exact type
When it happens
Trigger: Serializing any type graph that includes a slice whose element (or nested element) hits an unencodable case: reflect.Map, reflect.Array, or an unsupported kind, inside encodeType.
Common situations: DoFn signatures or PCollections with element types like []map[string]int or [][]byte-containing structs with unexported fields; pipelines exported for remote runners.
Related errors
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/8b8ff6cd84a1fc05.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/graphx/serialize.go:431
case reflect.Uint8:
return &v1pb.Type{Kind: v1pb.Type_UINT8}, nil
case reflect.Uint16:
return &v1pb.Type{Kind: v1pb.Type_UINT16}, nil
case reflect.Uint32:
return &v1pb.Type{Kind: v1pb.Type_UINT32}, nil
case reflect.Uint64:
return &v1pb.Type{Kind: v1pb.Type_UINT64}, nil
case reflect.Float32:
return &v1pb.Type{Kind: v1pb.Type_FLOAT32}, nil
case reflect.Float64:
return &v1pb.Type{Kind: v1pb.Type_FLOAT64}, nil
case reflect.String:
return &v1pb.Type{Kind: v1pb.Type_STRING}, nil
case reflect.Slice:
elm, err := encodeType(t.Elem())
if err != nil {
wrapped := errors.Wrap(err, "bad element type")
return nil, errors.WithContextf(wrapped, "encoding slice %v", t)
}
return &v1pb.Type{Kind: v1pb.Type_SLICE, Element: elm}, nil
case reflect.Struct:
var fields []*v1pb.Type_StructField
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.PkgPath != "" {
wrapped := errors.Errorf("type has unexported field: %v", f.Name)
return nil, errors.WithContextf(wrapped, "encoding struct %v", t)
}
fType, err := encodeType(f.Type)
if err != nil {
wrapped := errors.Wrap(err, "bad field type")
return nil, errors.WithContextf(wrapped, "encoding struct %v", t)View on GitHub (pinned to 12126d8942)