apache/beam · error

invoker: %v has > 5 return values, which is not permitted

Error message

invoker: %v has > 5 return values, which is not permitted

What it means

The Beam Go function invoker supports DoFns with at most 5 return values; the generated dispatch table (fn_arity.tmpl) only handles 1-5. When a user function returns 6 or more values, the invoker falls through the switch and panics. This is an arity-limit guard enforced at pipeline runtime when the DoFn is first invoked.

Source

Thrown at sdks/go/pkg/beam/core/runtime/exec/fn_arity.tmpl:65

			ret := n.fn.Fn.Call(n.args)

			// (5) Return direct output, if any. Input timestamp and windows are implicitly
			// propagated.
			switch len(ret) {
			case 0:
				return nil, nil
			case 1:
				return n.ret1(pn, ws, ts, ret[0])
			case 2:
				return n.ret2(pn, ws, ts, ret[0], ret[1])
			case 3:
				return n.ret3(pn, ws, ts, ret[0], ret[1], ret[2])
			case 4:
				return n.ret4(pn, ws, ts, ret[0], ret[1], ret[2], ret[3])
			case 5:
				return n.ret5(pn, ws, ts, ret[0], ret[1], ret[2], ret[3], ret[4])
			}
			panic(fmt.Sprintf("invoker: %v has > 5 return values, which is not permitted", n.fn.Fn.Name()))
		} 
	}
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Bundle multiple outputs into a struct or slice and return a single value
  2. Split the function into multiple DoFns, or use tags/emitters to emit multiple outputs instead of returning them
  3. Rewrite the function to return at most 5 values (per the invoker arity limit)

Example fix

// before
func (f *myFn) ProcessElement(ctx context.Context, el T) (A, B, C, D, E, F) { ... }

// after
type results struct{ A A; B B; C C; D D; E E; F F }
func (f *myFn) ProcessElement(ctx context.Context, el T) results { ... }
Defensive patterns

Strategy: validation

Validate before calling

if t := reflect.TypeOf(fn.ProcessElement); t.NumOut() > 5 {
    return fmt.Errorf("ProcessElement returns %d values; max 5", t.NumOut())
}

Type guard

func hasValidDoFnArity(fn interface{}) bool {
    m := reflect.ValueOf(fn).MethodByName("ProcessElement")
    if !m.IsValid() { return false }
    t := m.Type()
    return t.NumOut() <= 5
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        log.Fatalf("DoFn invocation failed: %v", r)
    }
}()

Prevention

When it happens

Trigger: Defining a DoFn ProcessElement (or other invocable function) that returns 6 or more values, then running a pipeline with that DoFn.

Common situations: Users attempting to return many values from a single ProcessElement instead of bundling them into a struct; auto-generated DoFns with large outputs.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/cd43ed275e82d281. Report an issue: GitHub.