apache/beam · error
mismatched restriction type in method
Error message
mismatched restriction type in method %v, parameter at index %v. got: %v, want: %v (from method %v). Ensure that all restrictions in an SDF are the same type.
What it means
All SDF restriction-bearing methods must share one restriction type. Beam validates that InitialWatermarkEstimatorState's restriction parameter (index 1) exactly equals the restriction type produced by CreateInitialRestriction (and used by CreateTracker). A mismatch fails validation with this error, which names the reference method that established the expected type.
Solutions
- Use the exact same named restriction type (as produced by CreateInitialRestriction and consumed by CreateTracker) in InitialWatermarkEstimatorState.
- Eliminate duplicate/same-named restriction types in different packages; pick one canonical type.
- Make value/pointer usage consistent across all restriction-bearing methods.
- Check for aliases or generics resolving to different underlying named types across methods.
Example fix
// before
func (f *fn) CreateTracker(rest MyRestriction) sdf.SdfBasicTracker { ... }
func (f *fn) InitialWatermarkEstimatorState(rt typex.EventTime, rest *MyRestriction) myState { ... }
// after
func (f *fn) CreateTracker(rest MyRestriction) sdf.SdfBasicTracker { ... }
func (f *fn) InitialWatermarkEstimatorState(rt typex.EventTime, rest MyRestriction) myState { ... } Defensive patterns
Strategy: validation
Validate before calling
// One canonical restriction type for the whole SDF
type MyRestriction struct{ Start, End int64 }
var _ func(MyRestriction) sdf.SdfBasicTracker = (*fn).CreateTracker
var _ func(string, typex.EventTime, MyRestriction) myState = (*fn).InitialWatermarkEstimatorState Prevention
- Define the restriction type once and reference it everywhere; never create aliases or duplicates.
- Be consistent about value vs pointer for the restriction across all methods.
- A compile-time assertion on CreateTracker's signature propagates the canonical type.
When it happens
Trigger: Declaring InitialWatermarkEstimatorState with a restriction type different from the one CreateInitialRestriction returns / CreateTracker takes — e.g. a same-named struct in another package, a pointer where others use a value, or a differently parameterized generic restriction.
Common situations: Creating an alias or duplicate restriction struct during refactoring so methods no longer share the identical named type; switching value vs pointer restriction types in some methods; copy-pasting methods between SDFs with same-named but distinct restriction types.
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
- Invalid output type in method
- Invalid output type in method
- invalid output type in method
- mismatched event time type in method
- Mismatched output type in method
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0e9b948448736b99.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/graph/fn.go:1284
switch name {
case initialWatermarkEstimatorStateName:
if len(method.Param) != numMainIn+2 {
err := errors.Errorf("unexpected number of params in method %v. got: %v, want: %v",
initialWatermarkEstimatorStateName, len(method.Param), numMainIn+2)
return errors.SetTopLevelMsgf(err, "unexpected number of parameters in method %v. "+
"got: %v, want: %v. Check that the signature conforms to the expected signature for %v, "+
"and that elements in SDF method parameters match elements in %v.",
initialWatermarkEstimatorStateName, len(method.Param), numMainIn+2, initialWatermarkEstimatorStateName, processElementName)
}
if method.Param[0].T != typex.EventTimeType {
err := errors.Errorf("unexpected parameter type in method %v, param %v. got: %v, want: %v",
initialWatermarkEstimatorStateName, 0, method.Param[0].T, typex.EventTimeType)
return errors.SetTopLevelMsgf(err, "mismatched event time type in method %v, "+
"parameter at index %v. got: %v, want: %v.",
initialWatermarkEstimatorStateName, 0, method.Param[0].T, typex.EventTimeType)
}
if method.Param[1].T != restT {
err := errors.Errorf("mismatched restriction type in method %v, param %v. got: %v, want: %v",
initialWatermarkEstimatorStateName, 1, method.Param[1].T, restT)
return errors.SetTopLevelMsgf(err, "mismatched restriction type in method %v, "+
"parameter at index %v. got: %v, want: %v (from method %v). "+
"Ensure that all restrictions in an SDF are the same type.",
initialWatermarkEstimatorStateName, 1, method.Param[1].T, restT, createTrackerName)
}
if err := validateSdfElementT(fn, initialWatermarkEstimatorStateName, method, numMainIn, 2); err != nil {
return err
}
if len(method.Ret) != 1 {
err := errors.Errorf("unexpected number of elements returned in method %v. got: %v, want %v",
initialWatermarkEstimatorStateName, len(method.Ret), 1)
return errors.SetTopLevelMsgf(err, "unexpected number of elements returned in method %v. "+
"got: %v, want %v. Check that the signature conforms to the expected signature for %v.",
initialWatermarkEstimatorStateName, len(method.Ret), 1, initialWatermarkEstimatorStateName)
}
if method.Ret[0].T != watermarkStateT {View on GitHub (pinned to 12126d8942)