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

  1. Inspect the full wrapped error context chain to find the deepest failing type in the slice element tree.
  2. Replace map/array elements with slices or structs of exported fields.
  3. Wrap unencodable element types as struct fields (beam issue 23101 workaround).
  4. 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

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)