apache/beam · error

Incompatible func type: got func

Error message

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

What it means

ToFunc0x4 adapts a generic reflectx Func into a Func0x4 (0 inputs, 4 outputs). It panics when the wrapped function's reflect type does not have exactly 0 inputs and 4 outputs. The library throws this eagerly so arity mismatches fail at wrapper-construction time instead of silently failing at call time.

Solutions

  1. Change the wrapped function to have exactly 0 inputs and 4 outputs, or update the call to the ToFunc/MakeFunc variant matching the actual arity (e.g. ToFunc1x4 if it takes 1 input).
  2. Check c.Type() with NumIn()/NumOut() before wrapping and pick the correct FuncN type.
  3. If the function needs different arity, register it with the matching MakeFuncNxM helper generated in calls.go.

Example fix

// before
f := reflectx.MakeFunc0x4(func() (int, int, int) { ... }) // panics: 3 outputs, want 4
// after
f := reflectx.MakeFunc0x4(func() (int, int, int, int) { return 1, 2, 3, 4 })
Defensive patterns

Strategy: validation

Validate before calling

t := c.Type()
if t.NumIn() != 0 || t.NumOut() != 4 {
    panic(fmt.Sprintf("func %v has %d ins/%d outs; ToFunc0x4 needs 0 ins/4 outs", t, t.NumIn(), t.NumOut()))
}

Type guard

func isFunc0x4(c reflectx.Func) bool {
    return c.Type().NumIn() == 0 && c.Type().NumOut() == 4
}

Try / catch

func safeToFunc0x4(c reflectx.Func) (f reflectx.Func0x4) {
    defer func() {
        if r := recover(); r != nil {
            log.Fatalf("ToFunc0x4 arity mismatch: %v", r)
        }
    }()
    return reflectx.ToFunc0x4(c)
}

Prevention

When it happens

Trigger: Calling reflectx.ToFunc0x4 (directly or via MakeFunc0x4) with a Func whose Type().NumIn() != 0 or Type().NumOut() != 4, e.g. wrapping a function that takes context parameters or returns fewer/more than 4 values.

Common situations: Hand-writing a DoFn emit function after changing its return count; passing a registered function whose signature was refactored (added an error return or input) while the MakeFunc0x4 call site was not updated; copy-pasting adapter code between arities.

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

Appendix: source

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

}

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

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

func (c *shimFunc0x4) Call0x4() (any, any, any, any) {
	ret := c.inner.Call([]any{})
	_ = ret
	return ret[0], ret[1], ret[2], ret[3]
}

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

func MakeFunc0x4(fn any) Func0x4 {
	return ToFunc0x4(MakeFunc(fn))
}

type Func1x0 interface {
	Func
	Call1x0(any)
}

type shimFunc1x0 struct {
	inner Func

View on GitHub (pinned to 12126d8942)