apache/beam · error
mismatched output type in method
Error message
mismatched output type in method %v, return value at index %v got: %v, want: %v (from method %v). Ensure that all watermark estimators in an SDF are the same type.
What it means
Beam Go validates that every watermark estimator method in a SplittableDoFn returns the same watermark state type. This error fires when a method's single return value's type differs from the watermark state type returned by the other estimator methods (e.g. a different WatermarkEstimator implementation's state type). Beam requires uniformity so state can be serialized and propagated consistently across bundles.
Solutions
- Make all watermark estimator methods in the SDF return the same watermark state type.
- Pick one WatermarkEstimator implementation and use its state type consistently across all methods.
- Search the DoFn for all methods taking/returning watermark state and align their types.
Example fix
// before
func (fn *MySDF) InitialWatermarkEstimatorState(et beam.EventTime, rt types.Type) watermark.ManualState { ... }
func (fn *MySDF) CreateWatermarkEstimatorState(s watermark.ManualState) watermark.State { ... }
// after
func (fn *MySDF) InitialWatermarkEstimatorState(et beam.EventTime, rt types.Type) watermark.State { ... }
func (fn *MySDF) CreateWatermarkEstimatorState(s watermark.State) watermark.State { ... } Defensive patterns
Strategy: validation
Validate before calling
// ensure all watermark state types agree
if reflect.TypeOf(initialRet) != reflect.TypeOf(createRet) {
return fmt.Errorf("watermark state types differ")
} Type guard
func sameStateType(a, b watermark.State) bool { return reflect.TypeOf(a) == reflect.TypeOf(b) } Try / catch
if err := beam.Run(ctx, ...); err != nil {
if strings.Contains(err.Error(), "mismatched output type") {
log.Fatalf("SDF watermark estimator methods must share one state type: %v", err)
}
return err
} Prevention
- Pick one WatermarkEstimator implementation per SDF and stick to it
- Grep the DoFn for `watermark.` return types and verify they match
- Add a compile-time assertion using a shared named type for all estimator state returns
When it happens
Trigger: An SDF has multiple watermark-estimator-related methods (e.g. InitialWatermarkEstimatorState and CreateWatermarkEstimatorState) whose return types differ, such as one returning watermark.ManualState and another watermark.State.
Common situations: Mixing estimator implementations in one SDF; refactoring one method to a different state type without updating the other; copying methods from two different SDF examples.
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
- emit parameter in method
- side input in method
- coder type must be identical to node type
- DoFn.WatermarkEstimatorParam…
- Duplicate state key used by and . Ensure that state keys…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d9c4807006c02a54.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/graph/fn.go:1335
watermarkEstimatorStateName, len(method.Param), 1, watermarkEstimatorStateName, processElementName)
}
if method.Param[0].T != watermarkEstimatorT {
err := errors.Errorf("mismatched watermark state type in method %v, return %v. got: %v, want: %v",
watermarkEstimatorStateName, 0, method.Param[0].T, watermarkEstimatorT)
return errors.SetTopLevelMsgf(err, "mismatched watermark state type in method %v, "+
"return value at index %v got: %v, want: %v (from method %v). "+
"Ensure that all watermark states in an SDF are the same type.",
watermarkEstimatorStateName, 0, method.Param[0].T, watermarkEstimatorT, watermarkEstimatorStateName)
}
if len(method.Ret) != 1 {
err := errors.Errorf("unexpected number of elements returned in method %v. got: %v, want %v",
watermarkEstimatorStateName, 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.",
watermarkEstimatorStateName, len(method.Ret), 1, watermarkEstimatorStateName)
}
if method.Ret[0].T != watermarkStateT {
err := errors.Errorf("mismatched output type in method %v, return %v. got: %v, want: %v",
watermarkEstimatorStateName, 0, method.Ret[0].T, watermarkStateT)
return errors.SetTopLevelMsgf(err, "mismatched output type in method %v, "+
"return value at index %v got: %v, want: %v (from method %v). "+
"Ensure that all watermark estimators in an SDF are the same type.",
watermarkEstimatorStateName, 0, method.Ret[0].T, watermarkStateT, watermarkEstimatorStateName)
}
}
}
return nil
}
func validateState(fn *DoFn, numIn mainInputs) error {
ps := fn.PipelineState()
if _, hasSp := fn.methods[processElementName].StateProvider(); hasSp {
if numIn == MainSingle {
err := errors.Errorf("ProcessElement uses a StateProvider, but is not keyed")
return errors.SetTopLevelMsgf(err, "ProcessElement uses a StateProvider, but is not keyed. "+View on GitHub (pinned to 12126d8942)