apache/beam · error

Incompatible func type: got func

Error message

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

What it means

reflectx.ToFunc4x4 wraps a generic reflectx.Func into a fixed-arity Func4x4 (4 inputs, 4 outputs). Before wrapping it asserts the underlying func's reflect.Type has exactly 4 inputs and 4 outputs; otherwise it panics with this message. Apache Beam's DoFn machinery uses these shims to call user functions efficiently, so an arity mismatch means the registration signature does not match what the pipeline expects.

Solutions

  1. Count the function's inputs and return values and adjust the signature to exactly 4 inputs and 4 outputs (adding named results or merging them as needed).
  2. Use the ToFuncN x M variant that matches the actual signature (e.g. ToFunc4x2) instead of ToFunc4x4.
  3. If using a DoFn struct, check that ProcessElement's parameter and return-list arity matches the fixed-arity registration being attempted.

Example fix

// before
func fn(a A, b B, c C, d D) (X, Y) { ... }
reflectx.ToFunc4x4(fn) // panics: 2 outputs

// after
func fn(a A, b B, c C, d D) (W, X, Y, Z) { ... }
reflectx.ToFunc4x4(fn)
Defensive patterns

Strategy: validation

Validate before calling

fn := reflect.TypeOf(fnAny)
if fn.Kind() == reflect.Func && fn.NumIn() == 4 && fn.NumOut() == 4 {
    _ = reflectx.ToFunc4x4(fnAny)
}

Type guard

func isFunc4x4(f interface{}) bool {
    t := reflect.TypeOf(f)
    return t != nil && t.Kind() == reflect.Func && t.NumIn() == 4 && t.NumOut() == 4
}

Try / catch

func safeToFunc4x4(c reflectx.Func) (f reflectx.Func4x4, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("ToFunc4x4 failed: %v", r)
        }
    }()
    return reflectx.ToFunc4x4(c), nil
}

Prevention

When it happens

Trigger: Calling reflectx.ToFunc4x4(c) where c.Type().NumIn() != 4 or c.Type().NumOut() != 4. Typically reached via beam.ParDo/beam.TryParDo registering a function whose signature has 4 emit-consumable inputs but not exactly 4 return values (e.g. returning (T, E, bool) or nothing).

Common situations: DoFn.ProcessElement-style functions written with the wrong number of return values after a refactor; adding an error or element type to a return tuple without updating arity; passing a 4-in/2-out function where a 4x4 signature (e.g. with context and emit) is expected.

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/584dc74b24747e50. Report an issue: GitHub.

Appendix: source

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

}

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

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

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

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

func MakeFunc4x4(fn any) Func4x4 {
	return ToFunc4x4(MakeFunc(fn))
}

type Func5x0 interface {
	Func
	Call5x0(any, any, any, any, any)
}

type shimFunc5x0 struct {
	inner Func

View on GitHub (pinned to 12126d8942)