{"record":{"id":"45c2cea05f091ace","repo":"apache/beam","slug":"errillegalparametersiniter","errorCode":null,"errorMessage":"errIllegalParametersInIter","messagePattern":"errIllegalParametersInIter","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/funcx/sideinput.go","lineNumber":92,"sourceCode":"\tif t.NumOut() != 1 || t.Out(0) != reflectx.Bool {\n\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).Kind() == reflect.Ptr && t.In(0).Elem() == typex.EventTimeType {\n\t\treturn nil, false, errors.New(errIllegalEventTimeInIter)\n\t}\n\tif t.NumIn()-skip > 2 || t.NumIn() == skip {\n\t\treturn nil, false, nil\n\t}\n\n\tfor i := skip; i < t.NumIn(); i++ {\n\t\tif ok, err := isOutParam(t.In(i)); !ok {\n\t\t\treturn nil, false, errors.Wrap(err, errIllegalParametersInIter)\n\t\t}\n\t\tif reflect.TypeOf((*any)(nil)).Elem() == t.In(i).Elem() && !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).Elem())\n\t}\n\treturn ret, true, nil\n}\n\nfunc isOutParam(t reflect.Type) (bool, error) {\n\tif t.Kind() != reflect.Ptr {\n\t\treturn false, errors.Errorf(\"Type %v of kind %v not allowed, must be ptr type\", t, t.Kind())\n\t}\n\tif typex.IsUniversal(t.Elem()) || typex.IsContainer(t.Elem()) {\n\t\treturn true, nil\n\t}\n\treturn typex.CheckConcrete(t.Elem())\n}","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/funcx/sideinput.go#L74-L110","documentation":"unfoldIter in sdks/go/pkg/beam/core/funcx/sideinput.go validates that a function used as an iterator side input has only parameters that are valid pointer side-input types. After the arity guard (0, 1, or 2 params beyond skip), every remaining parameter is checked with isOutParam; if any parameter is not a pointer to a universal/container/concrete PCollection type, the underlying error is wrapped with errIllegalParametersInIter and returned. The library throws it because iterator side inputs are mechanically unfolded from the function's reflect.Type, and a non-pointer parameter cannot back a PCollection iterator.","triggerScenarios":"Registering a DoFn or side-input function via funcx where a parameter (after the context/receiver skip) is not a pointer type, e.g. `func(ctx context.Context, i int)` or `func(kv KV)` passed to beam.ParDo / fx.UnfoldIter. Also triggered when a parameter is `*interface{}` (bare interface{} element) that is not a universal typex type.","commonSituations":"Writing a DoFn with a side input declared as a value or struct instead of a pointer (e.g. `s []string` instead of `s *[]string`); copying a Java/Python Beam side-input idiom into Go; refactoring a DoFn signature and dropping the `*`.","solutions":["Change each side-input parameter to a pointer to a valid PCollection element type, e.g. `func(i *int) bool` or `func(s *[]string)`.","If the parameter is `*interface{}`, replace it with a concrete typed pointer or a typex universal/container type.","Keep the parameter count within the allowed range (at most 2 parameters beyond the skipped context/receiver) so unfoldIter proceeds to parameter validation rather than bailing silently.","Call fx.IsIter(fn) or fx.IsMalformedIter(fn) in a unit test to validate the signature before running the pipeline."],"exampleFix":"// before\nfn := func(ctx context.Context, words []string, q string) bool { ... }\n// after\nfn := func(words *[]string, q *string) bool { ... }","handlingStrategy":"validation","validationCode":"// before registering the DoFn / side input\nif err := fx.IsMalformedIter(fn); err != nil {\n\treturn fmt.Errorf(\"invalid iter side-input signature for %T: %w\", fn, err)\n}","typeGuard":"func isValidIterSig(fn interface{}) bool {\n\tt := reflect.TypeOf(fn)\n\tif t == nil || t.Kind() != reflect.Func {\n\t\treturn false\n\t}\n\tfor i := 0; i < t.NumIn(); i++ {\n\t\tif t.In(i).Kind() != reflect.Ptr {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":"if _, _, err := fx.UnfoldIter(fn); err != nil {\n\t// err wraps errIllegalParametersInIter\n\treturn fmt.Errorf(\"side input rejected: %w\", err)\n}","preventionTips":["Always declare side-input parameters as pointers to concrete PCollection element types.","Never use interface{} as a side-input element type in Go Beam.","Add a unit test calling fx.IsIter/fx.IsMalformedIter for every DoFn side-input signature.","Avoid using context.Context-like extra params beyond the allowed count."],"tags":["go","beam","side-input","function-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"}