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

  1. Use the ToFunc variant matching the function's actual input and output counts (e.g., ToFunc2x1 for a 2-in/1-out func)
  2. Check c.Type().NumIn() and NumOut() (accounting for receiver vs closure differences) before choosing the converter
  3. 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

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


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)