{"record":{"id":"b07228cd9d45cab1","repo":"apache/beam","slug":"unexpected-number-of-parameters-in-method-v-got-v-want-v-fn","errorCode":null,"errorMessage":"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.","messagePattern":"unexpected number of parameters in method (.+?)\\. got: (.+?), want (.+?)\\. Check that the signature conforms to the expected signature for (.+?), and that elements in SDF method parameters match elements in (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":1312,"sourceCode":"\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\tinitialWatermarkEstimatorStateName, 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\tinitialWatermarkEstimatorStateName, len(method.Ret), 1, initialWatermarkEstimatorStateName)\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\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. \"+","sourceCodeStart":1294,"sourceCodeEnd":1330,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L1294-L1330","documentation":"In a stateful SDF, WatermarkEstimatorState must take exactly one parameter — the sdf.WatermarkEstimator whose state is being read. Beam validates len(method.Param) == 1 and throws this error when the method has zero parameters or extra ones (e.g. context or restriction), because the runner calls it with just the estimator.","triggerScenarios":"Declaring WatermarkEstimatorState(ctx context.Context, we sdf.WatermarkEstimator) or WatermarkEstimatorState(rest MyRestriction, we sdf.WatermarkEstimator); omitting the estimator parameter entirely.","commonSituations":"Adding context out of habit from other DoFn methods; copying ProcessElement's parameter style; misunderstanding which methods receive extra SDF parameters.","solutions":["Change WatermarkEstimatorState to take exactly one parameter of type sdf.WatermarkEstimator.","Move any needed context or restriction access into the estimator itself (store it when created) or into other methods.","Verify against the documented stateful SDF signature table.","Check the method name — Beam matches by exact name, so a differently named method won't satisfy this check."],"exampleFix":"// before\nfunc (f *fn) WatermarkEstimatorState(ctx context.Context, we sdf.WatermarkEstimator) myState { ... }\n// after\nfunc (f *fn) WatermarkEstimatorState(we sdf.WatermarkEstimator) myState {\n    return we.(*myWatermarkEstimator).state\n}","handlingStrategy":"validation","validationCode":"var _ func(sdf.WatermarkEstimator) myState = (*fn).WatermarkEstimatorState","typeGuard":null,"tryCatchPattern":null,"preventionTips":["WatermarkEstimatorState takes only the estimator — no context, no restriction.","Store any needed context data in the estimator when it's created.","Lock the signature with a compile-time assertion."],"tags":["go","apache-beam","sdf","watermark-estimator","parameter-count"],"backgroundTag":"invalid-argument-value","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"}