{"record":{"id":"32295a62c2522b07","repo":"apache/beam","slug":"errillegalparametersinemit","errorCode":null,"errorMessage":"errIllegalParametersInEmit","messagePattern":"errIllegalParametersInEmit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/funcx/output.go","lineNumber":85,"sourceCode":"\t\treturn nil, false, nil\n\t}\n\tif t.NumIn() == 0 {\n\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":67,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/funcx/output.go#L67-L101","documentation":"unfoldEmit validates emitter functions (func parameters used to emit output elements, e.g. func(string) in a DoFn). When one of the emitter's own parameters fails isInParam (not a universal/container type and typex.CheckConcrete rejects it), the error is wrapped as errIllegalParametersInEmit. Beam throws this because an emitter can only push values that are valid PCollection elements. Related hard rule in the same block: a bare interface{} (any) emitter parameter is rejected with \"Type interface{}{} isn't a supported PCollection type\".","triggerScenarios":"Registering a DoFn whose emit function parameter takes an invalid input type: e.g. func(func(any) bool), func(func(chan int) bool), func(func(map[string]int) bool), or func(func(T) bool) where T fails typex.CheckConcrete. Surfaces through IsEmit/IsMalformedEmit/UnfoldEmit and then funcx.New during beam.ParDo.","commonSituations":"Trying to emit generic/any values from a DoFn; emitting maps or channels directly; generics-era refactors that turned element types into interface{}; emitting pointer-to-interface types that concrete-type checking rejects.","solutions":["Change the emitter's parameter to a concrete PCollection element type (e.g. func(func(MyType) bool)).","Replace interface{} (any) with a concrete type, or use typex.Universal types (typex.T, typex.KV, typex.WindowedValue) if truly generic emission is needed.","Split map/struct emissions into concrete types or wrap them in typex.KV pairs.","Sanity-check the emitter with funcx.UnfoldEmit(reflect.TypeOf(emitter)) in a test to see exactly which parameter is rejected."],"exampleFix":"// before\nfunc (f *fn) ProcessElement(s string, emit func(any)) { emit(s) }\n// after\nfunc (f *fn) ProcessElement(s string, emit func(string)) { emit(s) }","handlingStrategy":"validation","validationCode":"emitType := reflect.TypeOf(emit)\ntypes, ok := funcx.UnfoldEmit(emitType)\nif !ok {\n    return fmt.Errorf(\"not a valid emitter: %v\", emitType)\n}\nfor _, et := range types {\n    if et == reflect.TypeOf((*any)(nil)).Elem() {\n        return errors.New(\"emitter parameter interface{} is not a supported PCollection type\")\n    }\n}","typeGuard":"func validEmitter(t reflect.Type) bool { _, ok := funcx.UnfoldEmit(t); return ok }","tryCatchPattern":"if ok, err := funcx.IsMalformedEmit(reflect.TypeOf(emitField)); ok {\n    return fmt.Errorf(\"emit %v unusable: %w\", reflect.TypeOf(emitField), err)\n}","preventionTips":["Type emitters with concrete element types only; avoid any/interface{}","Never emit maps, channels, or funcs directly","Validate custom emit signatures with funcx.UnfoldEmit before wiring them into DoFns"],"tags":["go","apache-beam","emitter","dofn-signature","reflection"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}