apache/beam · error
SplitRestriction has unexpected number of parameters
Error message
SplitRestriction has unexpected number of parameters: %v
What it means
The SplitRestriction function of an SDF must take between 2 and 4 parameters (element plus optional timestamp/etc., matching CreateInitialRestriction's inputs plus the restriction). initCallFn rejects any other arity with this error. The reported 'called by' newCreateInitialRestrictionInvoker reflects that all SDF invokers share the same init wiring.
Solutions
- Give SplitRestriction 2-4 parameters, e.g. func(el T, rest R) []R.
- Always include the element (and any timestamp parameter matching CreateInitialRestriction) in the signature.
- Remove extra parameters beyond the documented set.
- Unit-test the SDF with beam.TestPipeline so signature errors surface before deployment.
Example fix
// before
func (fn *mySdf) SplitRestriction(rest watermarksInterval) []watermarksInterval { ... }
// after
func (fn *mySdf) SplitRestriction(el string, rest watermarksInterval) []watermarksInterval { ... } Defensive patterns
Strategy: validation
Validate before calling
t := reflect.TypeOf(fn.SplitRestriction)
n := t.NumIn()
if n < 2 || n > 4 {
return fmt.Errorf("SplitRestriction must take 2-4 parameters, has %d", n)
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "SplitRestriction has unexpected number of parameters") {
// fix arity to 2-4, element first
}
return err
} Prevention
- Always include the element parameter in SplitRestriction.
- Mirror the parameter list of CreateInitialRestriction plus the restriction.
- Run a local TestPipeline smoke test for every new SDF.
When it happens
Trigger: Registering a SplitRestriction fn with fewer than 2 parameters (e.g. only the restriction) or more than 4, so no generated fast path matches and the default case errors at sdf_invokers_arity.go:138.
Common situations: Omitting the element parameter when writing a stateless splitter, or adding extra config parameters after refactoring; also happens when parameter types don't match so the reflected signature is treated as unknown arity.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- CreateInitialRestriction has unexpected number of parameters
- CreateTracker has unexpected number of parameters
- CreateWatermarkEstimator fn
- initial splitting returned 0 restrictions.
- InitialWatermarkEstimatorState fn
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/2a98f47edc731324.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/exec/sdf_invokers_arity.go:138
r0, r1 := fnT.Call2x2(n.args[0], n.args[1])
return r0, asError(r1)
}
case reflectx.Func3x2:
n.call = func() (splits any, err error) {
r0, r1 := fnT.Call3x2(n.args[0], n.args[1], n.args[2])
return r0, asError(r1)
}
case reflectx.Func4x2:
n.call = func() (splits any, err error) {
r0, r1 := fnT.Call4x2(n.args[0], n.args[1], n.args[2], n.args[3])
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
}View on GitHub (pinned to 12126d8942)