{"record":{"id":"cce0df53d2a8e97d","repo":"apache/beam","slug":"unexpected-number-of-params-in-method-v-got-v-want-v-or","errorCode":null,"errorMessage":"unexpected number of params in method %v. got: %v, want: %v or optionally %v if first param is of type context.Context","messagePattern":"unexpected number of params in method (.+?)\\. got: (.+?), want: (.+?) or optionally (.+?) if first param is of type context\\.Context","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":956,"sourceCode":"\t\tsplitRestrictionName:         num + 1,\n\t\trestrictionSizeName:          num + 1,\n\t\tcreateTrackerName:            1,\n\t\ttruncateRestrictionName:      num + 1,\n\t}\n\toptionalSdfs := map[string]bool{\n\t\ttruncateRestrictionName: true,\n\t}\n\treqReturnNum := 1\n\n\tfor _, name := range sdfNames {\n\t\tmethod, ok := fn.methods[name]\n\t\tif !ok && optionalSdfs[name] {\n\t\t\tcontinue\n\t\t}\n\n\t\treqParamNum := reqParamNums[name]\n\t\tif !sdfHasValidParamNum(method.Param, reqParamNum) {\n\t\t\terr := errors.Errorf(\"unexpected number of params in method %v. got: %v, want: %v or optionally %v \"+\n\t\t\t\t\"if first param is of type context.Context\", name, len(method.Param), reqParamNum, reqParamNum+1)\n\t\t\treturn errors.SetTopLevelMsgf(err, \"Unexpected number of parameters in method %v. \"+\n\t\t\t\t\"Got: %v, Want: %v or optionally %v if first param is of type context.Context. \"+\n\t\t\t\t\"Check that the signature conforms to the expected signature for %v, and that elements in SDF method \"+\n\t\t\t\t\"parameters match elements in %v.\", name, len(method.Param), reqParamNum, reqParamNum+1,\n\t\t\t\tname, processElementName)\n\t\t}\n\t\tif !sdfHasValidReturnNum(method.Ret, reqReturnNum) {\n\t\t\terr := errors.Errorf(\"unexpected number of returns in method %v. got: %v, want: %v or optionally %v \"+\n\t\t\t\t\"if last value is of type error\", name, len(method.Ret), reqReturnNum, reqReturnNum+1)\n\t\t\treturn errors.SetTopLevelMsgf(err, \"Unexpected number of return values in method %v. \"+\n\t\t\t\t\"Got: %v, Want: %v or optionally %v if last value is of type error. \"+\n\t\t\t\t\"Check that the signature conforms to the expected signature for %v.\",\n\t\t\t\tname, len(method.Ret), reqReturnNum, reqReturnNum+1, name)\n\t\t}\n\t}\n\treturn nil\n}","sourceCodeStart":938,"sourceCodeEnd":974,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L938-L974","documentation":"validateSdfSigNumbers checks that each required SDF method (e.g. CreateInitialRestriction, SplitRestriction, RestrictionSize, CreateTracker, ProcessElement) has an expected number of parameters; one extra leading context.Context parameter is tolerated. This error is thrown when a method's total parameter count is neither reqParamNum nor reqParamNum+1 with a leading context.Context.","triggerScenarios":"Declaring an SDF method with too few or too many parameters — e.g. CreateTracker with two params besides context, or ProcessElement missing its restriction-tracker parameter; also passing a non-context type as the extra first parameter.","commonSituations":"Copying method signatures from Java/Python SDF examples into Go; adding a context.Context not in the leading position; forgetting to add the RTracker param to ProcessElement when adding SDF methods; typos in parameter lists during refactoring.","solutions":["Adjust the method so it has exactly the required number of parameters for that SDF role, optionally preceded by one context.Context parameter.","If you added context.Context, confirm it is the FIRST parameter of the method.","For ProcessElement, ensure it takes the RTracker plus the same element (and optional key/value) parameters as CreateInitialRestriction.","Check the reqParamNums table in fn.go for the exact expected count of the method name reported in the error."],"exampleFix":"// before\nfunc (fn *myFn) CreateTracker(r myRestriction, extra int) *myTracker { ... }\n\n// after\nfunc (fn *myFn) CreateTracker(r myRestriction) *myTracker { ... }","handlingStrategy":"validation","validationCode":"// Validate param counts (allowing optional leading context.Context) before beam.TrySdf:\nfunc checkParamCount(t reflect.Type, name string, want int) error {\n    m, ok := t.MethodByName(name)\n    if !ok { return fmt.Errorf(\"missing method %s\", name) }\n    n := m.Type.NumIn() - 1\n    if n == want || (n == want+1 && m.Type.In(1) == reflect.TypeOf((*context.Context)(nil)).Elem()) {\n        return nil\n    }\n    return fmt.Errorf(\"%s: got %d params, want %d (+optional ctx)\", name, n, want)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always put context.Context first if used in SDF methods","Follow the canonical SDF signature table in the Beam Go docs","Add unit tests that construct the DoFn at pipeline-build time to fail fast"],"tags":["go","apache-beam","sdf","signature-validation","reflection"],"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-14T16:17:12.679Z"}