apache/beam · error
SplitRestriction has unexpected number of return values
Error message
SplitRestriction has unexpected number of return values: %v
What it means
The reflection invoker for the SDF method SplitRestriction expects the user method to return either (split restrictions...) as a single slice/value, or that plus an error. When the reflected call yields a return-value count the invoker does not recognize, it panics with this message. It is a signature-contract violation detected at pipeline construction/execution time.
Solutions
- Make SplitRestriction return exactly one value: the restriction slice (e.g. []MyRestriction)
- Or two values: ([]MyRestriction, error)
- Cross-check against the sdk splittable DoFn examples in sdks/go/pkg/beam/sdf
- Validate the DoFn with the direct runner tests before production
Example fix
// before
func (fn *MyDoFn) SplitRestriction(r MyRestriction, elem string) ([]MyRestriction, int, error) { ... }
// after
func (fn *MyDoFn) SplitRestriction(elem string, r MyRestriction) ([]MyRestriction, error) { ... } Defensive patterns
Strategy: validation
Validate before calling
t := reflect.TypeOf(fn.SplitRestriction)
if t.NumOut() != 1 && t.NumOut() != 2 {
panic("SplitRestriction must return ([]R) or ([]R, error)")
} Type guard
func validArity(m interface{}) bool {
n := reflect.TypeOf(m).NumOut()
return n == 1 || n == 2
} Prevention
- Return the restriction slice as the sole (or first) output
- Keep SDF lifecycle methods minimal — no extra diagnostics outputs
- Validate signatures with the direct runner before production
- Consult beam splittable DoFn examples when implementing drain/truncate
When it happens
Trigger: Implementing SplitRestriction with 0 or 3+ return values; returning (restrictions, somethingElse, error); reflection wiring mismatch caused by wrong method registration.
Common situations: Custom splitting logic hand-written with extra outputs; refactors that added a return value without updating the invoker contract; copying signatures from non-SDF DoFn examples.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- CreateInitialRestriction has unexpected number of return…
- TruncateRestriction has unexpected number of return values
- bad return type for
- beam.RegisterSchemaProvider: unsupported type kind for…
- CreateTracker has unexpected number of parameters
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/a185511e35fcc314.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/exec/sdf_invokers_arity.go:151
return r0, asError(r1)
}
default:
if len(n.fn.Param) < 2 || len(n.fn.Param) > 4 {
return errors.Errorf("SplitRestriction has unexpected number of parameters: %v", len(n.fn.Param))
}
n.call = func() (splits any, err error) {
ret := n.fn.Fn.Call(n.args)
switch len(ret) {
case 1:
return ret[0], nil
case 2:
return ret[0], asError(ret[1])
}
panic(fmt.Sprintf("SplitRestriction has unexpected number of return values: %v", len(ret)))
}
}
return nil
}
func (n *rsInvoker) initCallFn() error {
// Expects a signature of the form:
// (context.Context?, key?, value, restriction) (float64, error?)
// TODO(BEAM-9643): Link to full documentation.
switch fnT := n.fn.Fn.(type) {
case reflectx.Func2x1:
n.call = func() (size float64, err error) {
r0 := fnT.Call2x1(n.args[0], n.args[1])
return r0.(float64), nil
}
View on GitHub (pinned to 12126d8942)