{"record":{"id":"cdd4dc2e22489c14","repo":"apache/beam","slug":"invalid-number-of-main-input-params-in-method-v-got-v-want-v","errorCode":null,"errorMessage":"invalid number of main input params in method %v. got: %v, want: %v or %v","messagePattern":"invalid number of main input params in method (.+?)\\. got: (.+?), want: (.+?) or (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":913,"sourceCode":"// consistent with each other (for example, element and restriction types should\n// match with each other). Returns an error if one is found, or nil if the\n// types are all valid.\n// TODO(BEAM-3301): Once SDF documentation is added to ParDo, add a comment\n// here to refer to that for specific details about what needs to be consistent.\nfunc validateSdfSignatures(fn *Fn, numMainIn mainInputs) error {\n\tnum := int(numMainIn)\n\n\t// If number of main inputs is ambiguous, we check for consistency against\n\t// CreateInitialRestriction.\n\tif numMainIn == 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\tnum = paramNum\n\t\tdefault: // Can't infer because method has invalid # of main inputs.\n\t\t\terr := errors.Errorf(\"invalid number of main input params in method %v. got: %v, want: %v or %v\",\n\t\t\t\tcreateInitialRestrictionName, paramNum, int(MainSingle), int(MainKv))\n\t\t\treturn errors.SetTopLevelMsgf(err, \"Invalid number of main input parameters in method %v. \"+\n\t\t\t\t\"Got: %v, Want: %v or %v. Check that the signature conforms to the expected signature for %v, \"+\n\t\t\t\t\"and that elements in SDF method parameters match elements in %v.\",\n\t\t\t\tcreateInitialRestrictionName, paramNum, int(MainSingle), int(MainKv), createInitialRestrictionName, processElementName)\n\t\t}\n\t}\n\n\tif err := validateSdfSigNumbers(fn, num); err != nil {\n\t\treturn err\n\t}\n\tif err := validateSdfSigTypes(fn, num); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":895,"sourceCodeEnd":931,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L895-L931","documentation":"When a DoFn is registered as a Splittable DoFn (SDF), Beam Go infers the main-input shape from the signature of its CreateInitialRestriction method. The method must take exactly one element parameter (MainSingle, e.g. T) or exactly two (MainKv, e.g. K and V). If the reflected method has any other number of main input params, validateSdfSignatures (via AsDoFn) rejects the DoFn because restriction creation cannot be correlated with ProcessElement inputs.","triggerScenarios":"Registering a DoFn with beam.TrySdf/beam.Sdf where CreateInitialRestriction declares zero main-input params, three or more main-input params, or params Beam cannot map to ProcessElement's element (or key/value) parameters.","commonSituations":"Hand-written SDFs where CreateInitialRestriction was given extra context or options parameters as main inputs; refactoring ProcessElement from single element to KV (or vice versa) without updating CreateInitialRestriction; porting a Java SDF whose method signatures don't translate to the Go SDK's two allowed shapes.","solutions":["Change CreateInitialRestriction so its non-context parameters are exactly one element (single input) or exactly two (key and value), matching ProcessElement.","Verify the element types in CreateInitialRestriction match the element parameters of ProcessElement exactly.","Confirm the method is actually named CreateInitialRestriction and is attached to the DoFn struct so reflection finds the intended method.","If the function only needs context.Context or metadata, ensure those are not counted as main inputs — only element (and optional key) params count."],"exampleFix":"// before\nfunc (fn *myFn) CreateInitialRestriction(ctx context.Context, elem string, opts Options) myRestriction { ... }\n\n// after\nfunc (fn *myFn) CreateInitialRestriction(elem string) myRestriction { ... }","handlingStrategy":"validation","validationCode":"// Ensure CreateInitialRestriction's main-input shape before registration:\nfunc checkSdfMainInput(fn any) error {\n    m := reflect.TypeOf(fn).MethodByName(\"CreateInitialRestriction\")\n    if !m.IsValid { /* handle */ }\n    n := m.Type.NumIn() - 1 // minus receiver\n    if n == 1 || n == 2 { return nil }\n    return fmt.Errorf(\"CreateInitialRestriction must have 1 or 2 main-input params, got %d\", n)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Copy a known-good SDF signature template when writing new SDFs","Keep CreateInitialRestriction and ProcessElement element types defined once and reused","Compile-time assertion helpers from beam docs to validate SDF shapes early"],"tags":["go","apache-beam","sdf","reflection","signature-validation"],"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-14T16:17:12.679Z"}