apache/beam · error

Incompatible func type: got func %v with %v inputs and %v ou

Error message

Incompatible func type: got func %v with %v inputs and %v outputs, want 2 inputs and 4 outputs

What it means

reflectx.ToFunc2x4 converts a generic Func wrapper to a strongly-typed Func2x4 (2 inputs, 4 outputs). Before wrapping, it verifies the underlying reflect.Type has exactly NumIn()==2 and NumOut()==4; otherwise it panics with this message. The Beam Go SDK throws it to fail fast at pipeline-construction time rather than produce a function signature that later explodes when invoked via reflection. The panic message includes the actual func type plus its input and output counts so the mismatch is immediately diagnosable.

Source

Thrown at sdks/go/pkg/beam/core/util/reflectx/calls.go:639

}

func (c *shimFunc2x4) Type() reflect.Type {
	return c.inner.Type()
}

func (c *shimFunc2x4) Call(args []any) []any {
	return c.inner.Call(args)
}

func (c *shimFunc2x4) Call2x4(arg0, arg1 any) (any, any, any, any) {
	ret := c.inner.Call([]any{arg0, arg1})
	_ = ret
	return ret[0], ret[1], ret[2], ret[3]
}

func ToFunc2x4(c Func) Func2x4 {
	if c.Type().NumIn() != 2 || c.Type().NumOut() != 4 {
		panic(fmt.Sprintf("Incompatible func type: got func %v with %v inputs and %v outputs, want 2 inputs and 4 outputs", c.Type(), c.Type().NumIn(), c.Type().NumOut()))
	}
	if sc, ok := c.(Func2x4); ok {
		return sc
	}
	return &shimFunc2x4{inner: c}
}

func MakeFunc2x4(fn any) Func2x4 {
	return ToFunc2x4(MakeFunc(fn))
}

type Func3x0 interface {
	Func
	Call3x0(any, any, any)
}

type shimFunc3x0 struct {
	inner Func

View on GitHub (pinned to 12126d8942)

Solutions

  1. Print f.Type() (or fn.TypeOf) and change the wrapped function to have exactly 2 input parameters and 4 return values.
  2. If the function legitimately has a different arity, call the matching ToFuncNxM converter (ToFunc3x1, ToFunc2x2, ...) instead.
  3. If you only have a Func and need flexibility, keep using the generic Func and let Beam's dispatcher invoke it rather than coercing to Func2x4.
  4. Check for accidental closure wrapping: a helper that captured extra arguments still counts them in the signature only if declared as parameters; adjust the wrapper to declare exactly 2 params.

Example fix

// before
f := reflectx.ToFunc2x4(fn) // fn: func(a int, b string) (int, string, error) — 2 out, panics
// after
f := reflectx.ToFunc2x4(func(a int, b string) (int, string, bool, error) {
    return a, b, true, nil
})
Defensive patterns

Strategy: validation

Validate before calling

t := reflect.TypeOf(fn)
if t.NumIn() != 2 || t.NumOut() != 4 {
    panic(fmt.Sprintf("expected 2-in/4-out func, got %v (%d in, %d out)", t, t.NumIn(), t.NumOut()))
}
f := reflectx.ToFunc2x4(f)

Type guard

func isFunc2x4(fn any) bool {
    t := reflect.TypeOf(fn)
    return t != nil && t.Kind() == reflect.Func && t.NumIn() == 2 && t.NumOut() == 4
}

Try / catch

// Panics are not recoverable via try/catch in Go; use defer/recover at registration boundaries:
func safeToFunc2x4(f reflectx.Func) (out reflectx.Func2x4, err error) {
    defer func() { if r := recover(); r != nil { err = fmt.Errorf("ToFunc2x4: %v", r) } }()
    out = reflectx.ToFunc2x4(f)
    return
}

Prevention

When it happens

Trigger: Calling reflectx.ToFunc2x4(f) where f.Func.Type().NumIn() != 2 or f.Func.Type().NumOut() != 4 — e.g. passing a function with 1, 3, or more parameters, or returning 2 or 3 values instead of 4.

Common situations: Registering a DoFn/emit function whose signature drifted after refactoring (an extra context or error parameter added), wrapping a function that returns only (T, error) instead of 4 values, or Beam's internal signature selection picking a different arity than the user's function because beam.ParDo inferred the wrong registration.

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/7296d2ef1a4feead. Report an issue: GitHub.