apache/beam · error
Unexpected type: %v
Error message
Unexpected type: %v
What it means
inferCoder in sdks/go/pkg/beam/coder.go panics with "Unexpected type: %v" when the given FullType matches neither the atomic-kind switch nor any known composite kind, hitting the outer default. Every NewCoder, NewElementEncoder, NewElementDecoder, and coder-inference path funnels through this function, so an unclassifiable type is a fail-fast internal invariant violation.
Source
Thrown at sdks/go/pkg/beam/coder.go:274
switch t.Type() {
case typex.KVType:
return &coder.Coder{Kind: coder.KV, T: t, Components: c}, nil
case typex.CoGBKType:
return &coder.Coder{Kind: coder.CoGBK, T: t, Components: c}, nil
case typex.WindowedValueType:
// TODO(herohde) 4/15/2018: do we ever infer W types now that PCollections
// are non-windowed? We either need to know the windowing strategy or
// we should remove this case.
return &coder.Coder{Kind: coder.WindowedValue, T: t, Components: c, Window: coder.NewGlobalWindow()}, nil
case typex.ShardedKeyType:
return &coder.Coder{Kind: coder.ShardedKey, T: t, Components: c}, nil
default:
panic(fmt.Sprintf("Unexpected composite type: %v", t))
}
default:
panic(fmt.Sprintf("Unexpected type: %v", t))
}
}
func inferCoders(list []FullType) ([]*coder.Coder, error) {
var ret []*coder.Coder
for _, t := range list {
c, err := inferCoder(t)
if err != nil {
return nil, err
}
ret = append(ret, c)
}
return ret, nil
}
// protoEnc marshals the supplied proto.Message.
func protoEnc(in T) ([]byte, error) {
var p protoreflect.ProtoMessageView on GitHub (pinned to 12126d8942)
Solutions
- Identify the type from the panic message and replace it with a standard Beam-representable type (primitive, struct, slice, map, KV).
- If the type is legitimately new, add a case to inferCoder mapping its kind to a coder.Coder Kind.
- Align Beam SDK versions across pipeline submission and worker.
- Validate custom types with typex.New and confirm the kind is supported before building coders.
Example fix
// before
default:
panic(fmt.Sprintf("Unexpected type: %v", t))
// after
case typex.MyKind:
return &coder.Coder{Kind: coder.Custom, T: t}, nil
default:
panic(fmt.Sprintf("Unexpected type: %v", t)) Defensive patterns
Strategy: validation
Validate before calling
if t == nil || t.Kind() == 0 {
return nil, fmt.Errorf("cannot infer coder for unknown type: %v", t)
}
if _, err := beam.NewCoder(t.Type()); err != nil {
return nil, fmt.Errorf("type not coder-compatible: %w", err)
} Type guard
func isCoderSupported(t typex.FullType) bool {
return t != nil && typex.IsKnownKind(t.Kind())
} Try / catch
func inferSafe(t typex.FullType) (c *coder.Coder, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("coder inference panicked for type %v: %v", t, r)
}
}()
return beam.NewCoder(t.Type())
} Prevention
- Register custom typex kinds with the coder framework before use.
- Keep SDK versions aligned between submitter and runner.
- Validate all PCollection element types with NewCoder early at pipeline-construction time.
- Avoid hand-constructing typex.FullType values; use typex.New on concrete reflect.Types.
When it happens
Trigger: Passing a FullType whose typex.Kind is outside the enumerated supported kinds (e.g. a custom typex.Kind from an extension, or a hand-constructed FullType) into NewCoder / NewElementEncoder / NewElementDecoder / inferCoders.
Common situations: Third-party Beam extensions introducing new types; hand-built typex.FullType values in tests or wrappers; version skew where one side understands a type the other does not.
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
- inferCoder: unknown container kind %v
- Unexpected composite type: %v
- Invalid Coder
- err
- coder must not be nil
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ada9f3fdd68a9b9d.
Report an issue: GitHub.