apache/beam · error
Incompatible func type: got func
Error message
Incompatible func type: got func %v with %v inputs and %v outputs, want {{$in}} inputs and {{$out}} outputs What it means
reflectx's generated ToFunc{In}x{Out} converters wrap a generic Func as a strongly-typed Func{In}x{Out} shim. Before wrapping, it verifies the function's reflect type has exactly the expected number of inputs and outputs; a mismatch panics because the shim's call ABI would otherwise be violated. This is a template-time arity guard used by Beam's core function utilities.
Solutions
- Use the ToFunc variant matching the function's actual input and output counts (e.g., ToFunc2x1 for a 2-in/1-out func)
- Check c.Type().NumIn() and NumOut() (accounting for receiver vs closure differences) before choosing the converter
- Refactor the target function to the expected arity instead of forcing the wrong converter
Example fix
// before: function has 2 inputs but wrapped as 1x f := reflectx.ToFunc1x1(myTwoInputFunc) // after f := reflectx.ToFunc2x1(myTwoInputFunc)
Defensive patterns
Strategy: type-guard
Validate before calling
if c.Type().NumIn() != wantIn || c.Type().NumOut() != wantOut {
return fmt.Errorf("func has %d in / %d out, need %d in / %d out", c.Type().NumIn(), c.Type().NumOut(), wantIn, wantOut)
} Type guard
func matchesArity(c reflectx.Func, in, out int) bool {
return c.Type().NumIn() == in && c.Type().NumOut() == out
} Try / catch
defer func() {
if r := recover(); strings.Contains(fmt.Sprint(r), "Incompatible func type") {
log.Fatalf("reflectx converter arity mismatch: %v", r)
}
}() Prevention
- Match the ToFuncNxM variant to the function's actual signature
- Check NumIn/NumOut before wrapping callbacks
- Avoid changing function signatures without updating converter call sites
When it happens
Trigger: Calling a ToFuncNxM converter (e.g., ToFunc1x2) with a Func whose reflect.Type has a different NumIn/NumOut than N/M.
Common situations: Wrapping user callbacks during pipeline graph construction with the wrong arity converter; signature changes in user DoFn/combine functions after the converter call site was written.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- CreateInitialRestriction has unexpected number of return…
- CreateTracker has unexpected number of return values
- err
- Failed to optimize MergeAccumulators for combiner
- Incompatible func type: got func
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/5df665a17fa9cab6.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/util/reflectx/calls.tmpl:65
}
func (c *shimFunc{{$in}}x{{$out}}) Type() reflect.Type {
return c.inner.Type()
}
func (c *shimFunc{{$in}}x{{$out}}) Call(args []any) []any {
return c.inner.Call(args)
}
func (c *shimFunc{{$in}}x{{$out}}) Call{{$in}}x{{$out}}({{mkargs $in "arg%v" "any"}}) ({{mktuple $out "any"}}) {
ret := c.inner.Call([]any{ {{mktuplef $in "arg%v"}} })
_ = ret
return {{mktuplef $out "ret[%v]"}}
}
func ToFunc{{$in}}x{{$out}}(c Func) Func{{$in}}x{{$out}} {
if c.Type().NumIn() != {{$in}} || c.Type().NumOut() != {{$out}} {
panic(fmt.Sprintf("Incompatible func type: got func %v with %v inputs and %v outputs, want {{$in}} inputs and {{$out}} outputs", c.Type(), c.Type().NumIn(), c.Type().NumOut()))
}
if sc, ok := c.(Func{{$in}}x{{$out}}); ok {
return sc
}
return &shimFunc{{$in}}x{{$out}}{inner: c}
}
func MakeFunc{{$in}}x{{$out}}(fn any) Func{{$in}}x{{$out}} {
return ToFunc{{$in}}x{{$out}}(MakeFunc(fn))
}
{{end}}
{{end}}
View on GitHub (pinned to 12126d8942)