apache/beam · error
too many return values: %v
Error message
too many return values: %v
What it means
findOutbound in bind.go converts a function's return values into the outbound type: 0 returns means no output, 1 becomes a plain type, 2 becomes a KV, and any other count is rejected. This error is returned when a DoFn process method returns 3 or more values, which the framework cannot represent.
Source
Thrown at sdks/go/pkg/beam/core/graph/bind.go:112
return inbound, kinds, outbound, out, nil
}
func findOutbound(fn *funcx.Fn) ([]typex.FullType, error) {
ret := trimIllegal(returnTypes(funcx.SubReturns(fn.Ret, fn.Returns(funcx.RetValue)...)))
params := funcx.SubParams(fn.Param, fn.Params(funcx.FnEmit)...)
var outbound []typex.FullType
// The direct output is the "main" output, if any.
switch len(ret) {
case 0:
break // ok: no direct output.
case 1:
outbound = append(outbound, typex.New(ret[0]))
case 2:
outbound = append(outbound, typex.NewKV(typex.New(ret[0]), typex.New(ret[1])))
default:
return nil, errors.Errorf("too many return values: %v", ret)
}
for _, param := range params {
values, _ := funcx.UnfoldEmit(param.T)
trimmed := trimIllegal(values)
if len(trimmed) == 2 {
outbound = append(outbound, typex.NewKV(typex.New(trimmed[0]), typex.New(trimmed[1])))
} else {
outbound = append(outbound, typex.New(trimmed[0]))
}
}
return outbound, nil
}
func returnTypes(list []funcx.ReturnParam) []reflect.Type {
var ret []reflect.Type
for _, elm := range list {
ret = append(ret, elm.T)View on GitHub (pinned to 12126d8942)
Solutions
- Reduce returns to at most two values (single type or KV) plus the allowed error/context forms.
- Use emit functions (func(X) emitter parameters) to produce multiple outputs instead of multiple return values.
- Pack multiple values into a struct or beam KV type and return that single value.
Example fix
// before
func (f *myFn) ProcessElement(ctx context.Context, s string) (int, string, error) { ... } // 3 returns
// after
func (f *myFn) ProcessElement(s string, emitStr func(string)) (int, error) { emitStr(s); return len(s), nil } Defensive patterns
Strategy: validation
Validate before calling
if t := reflect.TypeOf(fn); t.NumOut() > 3 { // e.g. 2 values + error
return fmt.Errorf("fn returns %d values; max supported is a single value or KV (plus error)", t.NumOut())
} Prevention
- Return at most one value or a KV from process methods.
- Use emitter functions for multiple outputs.
- Model multi-field results as a struct or beam.KV.
When it happens
Trigger: Registering a DoFn whose ProcessElement returns 3+ values, e.g. (KV, T, error) or (A, B, C, error), via graph.Bind/newDoFnNode during pipeline construction.
Common situations: Wanting to emit multiple distinct outputs from one method - developers return them instead of using separate emitters; porting code that returns a tuple plus error; accidental extra return of a debug value.
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
- first main input parameter must be a value type
- ProcessElement doesn't use a TimerProvider, but Timer field
- ProcessElement uses a TimerProvider, but no Timer fields are
- bad parameter type for %s: %v
- not enough required parameters: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/6e6f43d9aa8a6d45.
Report an issue: GitHub.