{"record":{"id":"90d192420e78ea62","repo":"apache/beam","slug":"type-interface-isn-t-a-supported-pcollection-type","errorCode":null,"errorMessage":"Type interface{} isn't a supported PCollection type","messagePattern":"Type interface(.+?) isn't a supported PCollection type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/funcx/output.go","lineNumber":88,"sourceCode":"\t\treturn nil, false, nil\n\t}\n\n\tvar ret []reflect.Type\n\tskip := 0\n\tif t.In(0) == typex.EventTimeType {\n\t\tret = append(ret, typex.EventTimeType)\n\t\tskip = 1\n\t}\n\tif t.NumIn()-skip > 2 || t.NumIn() == skip {\n\t\treturn nil, false, nil\n\t}\n\temptyInterface := reflect.TypeOf((*any)(nil)).Elem()\n\tfor i := skip; i < t.NumIn(); i++ {\n\t\tif ok, err := isInParam(t.In(i)); !ok {\n\t\t\treturn nil, false, errors.Wrap(err, errIllegalParametersInEmit)\n\t\t}\n\t\tif ((t.In(i).Kind() == reflect.Ptr && t.In(i).Elem() == emptyInterface) || t.In(i) == emptyInterface) && !typex.IsUniversal(t.In(i)) {\n\t\t\treturn nil, false, errors.New(\"Type interface{} isn't a supported PCollection type\")\n\t\t}\n\t\tret = append(ret, t.In(i))\n\t}\n\treturn ret, true, nil\n}\n\nfunc isInParam(t reflect.Type) (bool, error) {\n\tif typex.IsUniversal(t) || typex.IsContainer(t) {\n\t\treturn true, nil\n\t}\n\treturn typex.CheckConcrete(t)\n}\n","sourceCodeStart":70,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/funcx/output.go#L70-L101","documentation":"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).","triggerScenarios":"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{}`.","commonSituations":"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.","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."],"exampleFix":"// before\nfunc (fn *myFn) ProcessElement(e func(any), v string) {}\n// after\nfunc (fn *myFn) ProcessElement(e func(int), v string) {}","handlingStrategy":"validation","validationCode":"func hasAnyEmitParam(fn reflect.Type) bool {\n    anyT := reflect.TypeOf((*any)(nil)).Elem()\n    for i := 0; i < fn.NumIn(); i++ {\n        p := fn.In(i)\n        if (p.Kind() == reflect.Ptr && p.Elem() == anyT) || p == anyT {\n            return true\n        }\n    }\n    return false\n}","typeGuard":"func isConcrete(t reflect.Type) bool { return t != nil && t != reflect.TypeOf((*any)(nil)).Elem() }","tryCatchPattern":null,"preventionTips":["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."],"tags":["go","beam","ptransform","type-system"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}