{"record":{"id":"0d780d582a6fe26f","repo":"apache/beam","slug":"unexpected-number-of-parameters-in-method-v-got-v-want-v","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":1269,"sourceCode":"\n\t// If number of main inputs is ambiguous, we check for consistency against\n\t// CreateInitialRestriction.\n\tif numMainIn == int(MainUnknown) {\n\t\tinitialRestFn := fn.methods[createInitialRestrictionName]\n\t\tparamNum := len(initialRestFn.Params(funcx.FnValue))\n\n\t\tswitch paramNum {\n\t\tcase int(MainSingle), int(MainKv):\n\t\t\tnumMainIn = paramNum\n\t\t}\n\t}\n\n\tfor _, name := range watermarkEstimationNames {\n\t\tmethod := fn.methods[name]\n\t\tswitch name {\n\t\tcase initialWatermarkEstimatorStateName:\n\t\t\tif len(method.Param) != numMainIn+2 {\n\t\t\t\terr := errors.Errorf(\"unexpected number of params in method %v. got: %v, want: %v\",\n\t\t\t\t\tinitialWatermarkEstimatorStateName, len(method.Param), numMainIn+2)\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\tinitialWatermarkEstimatorStateName, len(method.Param), numMainIn+2, initialWatermarkEstimatorStateName, processElementName)\n\t\t\t}\n\t\t\tif method.Param[0].T != typex.EventTimeType {\n\t\t\t\terr := errors.Errorf(\"unexpected parameter type in method %v, param %v. got: %v, want: %v\",\n\t\t\t\t\tinitialWatermarkEstimatorStateName, 0, method.Param[0].T, typex.EventTimeType)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"mismatched event time type in method %v, \"+\n\t\t\t\t\t\"parameter at index %v. got: %v, want: %v.\",\n\t\t\t\t\tinitialWatermarkEstimatorStateName, 0, method.Param[0].T, typex.EventTimeType)\n\t\t\t}\n\t\t\tif method.Param[1].T != restT {\n\t\t\t\terr := errors.Errorf(\"mismatched restriction type in method %v, param %v. got: %v, want: %v\",\n\t\t\t\t\tinitialWatermarkEstimatorStateName, 1, method.Param[1].T, restT)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"mismatched restriction type in method %v, \"+\n\t\t\t\t\t\"parameter at index %v. got: %v, want: %v (from method %v). \"+","sourceCodeStart":1251,"sourceCodeEnd":1287,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L1251-L1287","documentation":"For a stateful SDF, InitialWatermarkEstimatorState must accept the same main-input elements that ProcessElement accepts, plus two extra parameters (event time and the restriction). Beam validates len(method.Param) == numMainIn + 2 and throws this error when the parameter count differs, since it cannot map the ProcessElement inputs onto the state-initialization call.","triggerScenarios":"InitialWatermarkEstimatorState declared with fewer parameters (e.g. just event time and restriction) or more parameters (extra context/options not in ProcessElement) than ProcessElement's main inputs + 2; ProcessElement's element set changed without updating InitialWatermarkEstimatorState.","commonSituations":"Adding a keyed or side-input parameter to ProcessElement without mirroring it in InitialWatermarkEstimatorState; trimming parameters for brevity; hand-writing the stateful method set with the wrong arity after copying a stateless SDF.","solutions":["Give InitialWatermarkEstimatorState exactly the same main-input parameters as ProcessElement (same order), plus (typex.EventTime, restriction) appended.","Count ProcessElement's main input parameters carefully (excluding context, watermark-estimator, event-time, and emit parameters) and match that count.","Beam requires exact arity: remove extra parameters or add them to ProcessElement too.","Compare against a working SDF example in the Beam repo for the same estimation style."],"exampleFix":"// before (ProcessElement takes element; state initializer missing it)\nfunc (f *fn) InitialWatermarkEstimatorState(rt typex.EventTime, rest MyRestriction) myState { return myState{} }\n// after\nfunc (f *fn) InitialWatermarkEstimatorState(element string, rt typex.EventTime, rest MyRestriction) myState {\n    return myState{}\n}\n// matches: func (f *fn) ProcessElement(element string, wec sdf.WatermarkEstimator, emit func(string))","handlingStrategy":"validation","validationCode":"// Arity check: main inputs of ProcessElement + 2\ntype pSig func(string, sdf.WatermarkEstimator, func(string))\ntype iwSig func(string, typex.EventTime, MyRestriction) myState\nvar _ = func() bool { var a pSig; var b iwSig; return a != nil && b != nil }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mirror ProcessElement's main-input parameters one-for-one in InitialWatermarkEstimatorState.","Append (typex.EventTime, restriction) after the mirrored parameters, never before.","Recount parameters after any ProcessElement signature change."],"tags":["go","apache-beam","sdf","watermark-estimator","parameter-count"],"backgroundTag":"missing-required-argument","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"}