{"record":{"id":"e16efa4188b1c727","repo":"apache/beam","slug":"incompatible-func-type-got-func-v-with-v-inputs-and-v-e16efa","errorCode":null,"errorMessage":"Incompatible func type: got func %v with %v inputs and %v outputs, want 3 inputs and 2 outputs","messagePattern":"Incompatible func type: got func (.+?) with (.+?) inputs and (.+?) outputs, want 3 inputs and 2 outputs","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/util/reflectx/calls.go","lineNumber":762,"sourceCode":"}\n\nfunc (c *shimFunc3x2) Type() reflect.Type {\n\treturn c.inner.Type()\n}\n\nfunc (c *shimFunc3x2) Call(args []any) []any {\n\treturn c.inner.Call(args)\n}\n\nfunc (c *shimFunc3x2) Call3x2(arg0, arg1, arg2 any) (any, any) {\n\tret := c.inner.Call([]any{arg0, arg1, arg2})\n\t_ = ret\n\treturn ret[0], ret[1]\n}\n\nfunc ToFunc3x2(c Func) Func3x2 {\n\tif c.Type().NumIn() != 3 || c.Type().NumOut() != 2 {\n\t\tpanic(fmt.Sprintf(\"Incompatible func type: got func %v with %v inputs and %v outputs, want 3 inputs and 2 outputs\", c.Type(), c.Type().NumIn(), c.Type().NumOut()))\n\t}\n\tif sc, ok := c.(Func3x2); ok {\n\t\treturn sc\n\t}\n\treturn &shimFunc3x2{inner: c}\n}\n\nfunc MakeFunc3x2(fn any) Func3x2 {\n\treturn ToFunc3x2(MakeFunc(fn))\n}\n\ntype Func3x3 interface {\n\tFunc\n\tCall3x3(any, any, any) (any, any, any)\n}\n\ntype shimFunc3x3 struct {\n\tinner Func","sourceCodeStart":744,"sourceCodeEnd":780,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/util/reflectx/calls.go#L744-L780","documentation":"reflectx.ToFunc3x2 converts a generic Func to a strongly-typed Func3x2 (3 inputs, 2 outputs). It panics if the underlying reflect.Type does not have exactly NumIn()==3 and NumOut()==2. The Beam Go SDK uses this guard so reflection-based calls in the pipeline always match the shim's declared signature, failing fast with the actual type and counts in the panic message.","triggerScenarios":"Calling reflectx.ToFunc3x2(f) where f.Type().NumIn() != 3 (e.g. 2 or 4 params) or f.Type().NumOut() != 2 (e.g. 1 return value, or 3 returns).","commonSituations":"A function that dropped its error return after refactoring (now 1 output), a function that gained a third return, or wrapping a function whose context/emitter parameter was added or removed, changing the input arity to 2 or 4.","solutions":["Change the function to have exactly 3 parameters and exactly 2 return values.","For a single return value, use ToFunc3x1; for no returns, ToFunc3x0.","Print reflect.TypeOf(fn) and compare NumIn/NumOut against the target 3x2 shape before wrapping.","If the arity legitimately differs, register the function through the higher-level beam API (beam.ParDo with a typed DoFn) instead of manual reflectx coercion."],"exampleFix":"// before\nf := reflectx.ToFunc3x2(func(a int, b string, c bool) int { return a }) // 1 output, panics\n// after\nf := reflectx.ToFunc3x2(func(a int, b string, c bool) (int, bool) { return a, c })","handlingStrategy":"validation","validationCode":"t := reflect.TypeOf(fn)\nif t.NumIn() != 3 || t.NumOut() != 2 {\n    panic(fmt.Sprintf(\"expected 3-in/2-out func, got %v (%d in, %d out)\", t, t.NumIn(), t.NumOut()))\n}\nf := reflectx.ToFunc3x2(f)","typeGuard":"func isFunc3x2(fn any) bool {\n    t := reflect.TypeOf(fn)\n    return t != nil && t.Kind() == reflect.Func && t.NumIn() == 3 && t.NumOut() == 2\n}","tryCatchPattern":"func safeToFunc3x2(f reflectx.Func) (out reflectx.Func3x2, err error) {\n    defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"ToFunc3x2: %v\", r) } }()\n    out = reflectx.ToFunc3x2(f)\n    return\n}","preventionTips":["Keep the converter call adjacent to the function definition so edits to one force review of the other.","Count returns including errors before choosing NxM.","Add tests asserting reflect type arity for every wrapped function.","Avoid copy-pasting converter names across functions with different arities."],"tags":["go","apache-beam","reflection","panic","function-signature"],"backgroundTag":"type-mismatch","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"}