apache/beam · error
Type interface{} isn't a supported PCollection type
Error message
Type interface{} isn't a supported PCollection type What it means
Apache Beam Go SDK rejects DoFn/emit function parameters (or return values reached via emit signatures) typed as plain `interface{}` (any), because Beam needs a concrete, coder-encodable PCollection element type. Unbounded `any` cannot be mapped to a Beam type descriptor or default coder. The check is skipped only for types marked as universal (typex.IsUniversal).
Source
Thrown at sdks/go/pkg/beam/core/funcx/output.go:88
return nil, false, nil
}
var ret []reflect.Type
skip := 0
if t.In(0) == typex.EventTimeType {
ret = append(ret, typex.EventTimeType)
skip = 1
}
if t.NumIn()-skip > 2 || t.NumIn() == skip {
return nil, false, nil
}
emptyInterface := reflect.TypeOf((*any)(nil)).Elem()
for i := skip; i < t.NumIn(); i++ {
if ok, err := isInParam(t.In(i)); !ok {
return nil, false, errors.Wrap(err, errIllegalParametersInEmit)
}
if ((t.In(i).Kind() == reflect.Ptr && t.In(i).Elem() == emptyInterface) || t.In(i) == emptyInterface) && !typex.IsUniversal(t.In(i)) {
return nil, false, errors.New("Type interface{} isn't a supported PCollection type")
}
ret = append(ret, t.In(i))
}
return ret, true, nil
}
func isInParam(t reflect.Type) (bool, error) {
if typex.IsUniversal(t) || typex.IsContainer(t) {
return true, nil
}
return typex.CheckConcrete(t)
}
View on GitHub (pinned to 12126d8942)
Solutions
- Replace the `interface{}`/`any` parameter with a concrete element type (e.g. string, KV<string,int>) in the emit function signature.
- If generic behavior is truly intended, mark the type as universal via typex.IsUniversal-supported declarations (e.g. use typex.T or a universal type marker) instead of bare `any`.
- Use Beam generics helpers (beam.ParDo with typed DoFn structs) so signatures are inferred with concrete types.
- Check upstream callers of UnfoldEmit to see which signature is being rejected and fix the DoFn method definition.
Example fix
// before
func (fn *myFn) ProcessElement(e func(any), v string) {}
// after
func (fn *myFn) ProcessElement(e func(int), v string) {} Defensive patterns
Strategy: validation
Validate before calling
func hasAnyEmitParam(fn reflect.Type) bool {
anyT := reflect.TypeOf((*any)(nil)).Elem()
for i := 0; i < fn.NumIn(); i++ {
p := fn.In(i)
if (p.Kind() == reflect.Ptr && p.Elem() == anyT) || p == anyT {
return true
}
}
return false
} Type guard
func isConcrete(t reflect.Type) bool { return t != nil && t != reflect.TypeOf((*any)(nil)).Elem() } Prevention
- Never type DoFn emit/element parameters as `any` or `interface{}`; always use concrete types.
- Prefer beam.ParDo with typed DoFn structs so the compiler checks signatures.
- Add a unit test that constructs each DoFn via funcx/AsDoFn validation before running pipelines.
When it happens
Trigger: Defining a DoFn whose ProcessElement emits via a function passed to reflection-based unfolding (unfoldEmit, called from IsEmit/UnfoldEmit) where an input parameter is `any` or `*any` and not declared universal — e.g. `func(e Emitter<any>, v string)` or a callback parameter of type `interface{}`.
Common situations: Writing generic helpers over reflect.Type, migrating code from `interface{}` placeholders after refactoring, or hand-rolling emit signatures in custom combinators/transform builders instead of concrete element types.
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
- Type interface{} isn't a supported PCollection type
- Iterators with timestamp values (<ET,V> and <ET, K, V>) are
- too few params
- too few inputs: forgot an input or to annotate options?
- too many inputs
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/90d192420e78ea62.
Report an issue: GitHub.