{"record":{"id":"e0e5d2e0a7913466","repo":"apache/beam","slug":"mismatched-watermark-state-type-in-method-v-return-value-at","errorCode":null,"errorMessage":"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.","messagePattern":"mismatched watermark state type in method (.+?), return value at index (.+?) got: (.+?), want: (.+?) \\(from method (.+?)\\)\\. Ensure that all watermark states in an SDF are the same type\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":1320,"sourceCode":"\t\t\tif method.Ret[0].T != watermarkStateT {\n\t\t\t\terr := errors.Errorf(\"mismatched output type in method %v, return %v. got: %v, want: %v\",\n\t\t\t\t\tcreateWatermarkEstimatorName, 0, method.Ret[0].T, watermarkStateT)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"mismatched output type in method %v, \"+\n\t\t\t\t\t\"return value at index %v got: %v, want: %v (from method %v). \"+\n\t\t\t\t\t\"Ensure that all watermark states in an SDF are the same type.\",\n\t\t\t\t\tcreateWatermarkEstimatorName, 0, method.Ret[0].T, watermarkStateT, createWatermarkEstimatorName)\n\t\t\t}\n\t\tcase watermarkEstimatorStateName:\n\t\t\tif len(method.Param) != 1 {\n\t\t\t\terr := errors.Errorf(\"unexpected number of params in method %v. got: %v, want %v\",\n\t\t\t\t\twatermarkEstimatorStateName, len(method.Param), 1)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"unexpected number of parameters in method %v. \"+\n\t\t\t\t\t\"got: %v, want %v. Check that the signature conforms to the expected signature for %v, \"+\n\t\t\t\t\t\"and that elements in SDF method parameters match elements in %v.\",\n\t\t\t\t\twatermarkEstimatorStateName, len(method.Param), 1, watermarkEstimatorStateName, processElementName)\n\t\t\t}\n\t\t\tif method.Param[0].T != watermarkEstimatorT {\n\t\t\t\terr := errors.Errorf(\"mismatched watermark state type in method %v, return %v. got: %v, want: %v\",\n\t\t\t\t\twatermarkEstimatorStateName, 0, method.Param[0].T, watermarkEstimatorT)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"mismatched watermark state type in method %v, \"+\n\t\t\t\t\t\"return value at index %v got: %v, want: %v (from method %v). \"+\n\t\t\t\t\t\"Ensure that all watermark states in an SDF are the same type.\",\n\t\t\t\t\twatermarkEstimatorStateName, 0, method.Param[0].T, watermarkEstimatorT, watermarkEstimatorStateName)\n\t\t\t}\n\t\t\tif len(method.Ret) != 1 {\n\t\t\t\terr := errors.Errorf(\"unexpected number of elements returned in method %v. got: %v, want %v\",\n\t\t\t\t\twatermarkEstimatorStateName, len(method.Ret), 1)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"unexpected number of elements returned in method %v. \"+\n\t\t\t\t\t\"got: %v, want %v. Check that the signature conforms to the expected signature for %v.\",\n\t\t\t\t\twatermarkEstimatorStateName, len(method.Ret), 1, watermarkEstimatorStateName)\n\t\t\t}\n\t\t\tif method.Ret[0].T != watermarkStateT {\n\t\t\t\terr := errors.Errorf(\"mismatched output type in method %v, return %v. got: %v, want: %v\",\n\t\t\t\t\twatermarkEstimatorStateName, 0, method.Ret[0].T, watermarkStateT)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"mismatched output type in method %v, \"+\n\t\t\t\t\t\"return value at index %v got: %v, want: %v (from method %v). \"+","sourceCodeStart":1302,"sourceCodeEnd":1338,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L1302-L1338","documentation":"WatermarkEstimatorState's sole parameter must be exactly the sdf.WatermarkEstimator interface type. Beam validates method.Param[0].T against watermarkEstimatorT and throws this error when the parameter is a different type, since it passes the constructed estimator to this method.","triggerScenarios":"Declaring WatermarkEstimatorState(state myState) (reading state directly instead of the estimator); using a concrete estimator type or pointer where Beam expects the sdf.WatermarkEstimator interface parameter.","commonSituations":"Confusing the estimator object with the estimator state in the signature; writing the state-extraction method to take the state struct instead; following outdated or inconsistent examples.","solutions":["Change the parameter type to sdf.WatermarkEstimator and type-assert inside to your concrete estimator.","Ensure CreateWatermarkEstimator returns a value assignable to sdf.WatermarkEstimator so the round trip type-checks.","If you intended a state-parameter method, that's InitialWatermarkEstimatorState / CreateWatermarkEstimator — fix the method name instead.","Follow the canonical stateful SDF example so all watermark method signatures stay consistent."],"exampleFix":"// before\nfunc (f *fn) WatermarkEstimatorState(st myState) myState { return st }\n// after\nfunc (f *fn) WatermarkEstimatorState(we sdf.WatermarkEstimator) myState {\n    return we.(*myWatermarkEstimator).state\n}","handlingStrategy":"type-guard","validationCode":"var _ func(sdf.WatermarkEstimator) myState = (*fn).WatermarkEstimatorState","typeGuard":"func asWatermarkEstimator(v any) (sdf.WatermarkEstimator, bool) {\n    we, ok := v.(sdf.WatermarkEstimator)\n    return we, ok\n}","tryCatchPattern":null,"preventionTips":["The parameter must be the sdf.WatermarkEstimator interface, not the state struct.","Type-assert to your concrete estimator inside the method body.","Keep estimator (object) and state (value) concepts distinct when writing signatures."],"tags":["go","apache-beam","sdf","watermark-estimator","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}