{"record":{"id":"2b95f6f28594eed3","repo":"apache/beam","slug":"method-v-has-invalid-parameters-only-allowed-an-optional","errorCode":null,"errorMessage":"method %v has invalid parameters, only allowed an optional context.Context","messagePattern":"method (.+?) has invalid parameters, only allowed an optional context\\.Context","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":578,"sourceCode":"\t\tprocessFnEmits = processFn.Param[0:0]\n\t}\n\tif startFn, ok := fn.methods[startBundleName]; ok {\n\t\tif err := validateEmits(processFnEmits, startFn, startBundleName); err != nil {\n\t\t\treturn nil, addContext(err, fn)\n\t\t}\n\t}\n\tif finishFn, ok := fn.methods[finishBundleName]; ok {\n\t\tif err := validateEmits(processFnEmits, finishFn, finishBundleName); err != nil {\n\t\t\treturn nil, addContext(err, fn)\n\t\t}\n\t}\n\n\t// Check that Setup and Teardown have no parameters other than Context.\n\tfor _, name := range []string{setupName, teardownName} {\n\t\tif method, ok := fn.methods[name]; ok {\n\t\t\tparams := method.Param\n\t\t\tif len(params) > 1 || (len(params) == 1 && params[0].Kind != funcx.FnContext) {\n\t\t\t\terr := errors.Errorf(\n\t\t\t\t\t\"method %v has invalid parameters, \"+\n\t\t\t\t\t\t\"only allowed an optional context.Context\", name)\n\t\t\t\terr = errors.SetTopLevelMsgf(err,\n\t\t\t\t\t\"Method %v of DoFns should have no parameters other than \"+\n\t\t\t\t\t\t\"an optional context.Context, but invalid parameters are \"+\n\t\t\t\t\t\t\"present in DoFn %v.\",\n\t\t\t\t\tname, fn.Name())\n\t\t\t\treturn nil, addContext(err, fn)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check that none of the methods (except ProcessElement) have any return\n\t// values other than error.\n\tfor _, name := range []string{setupName, startBundleName, finishBundleName, teardownName} {\n\t\tif method, ok := fn.methods[name]; ok {\n\t\t\treturns := method.Ret\n\t\t\tif len(returns) > 1 || (len(returns) == 1 && returns[0].Kind != funcx.RetError) {","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L560-L596","documentation":"Setup and Teardown methods on a DoFn may take at most one parameter, which must be context.Context. AsDoFn rejects any other parameter list at fn.go:578, with a friendly top-level message naming the DoFn.","triggerScenarios":"Defining Setup/Teardown with extra or non-context parameters, e.g. Setup(cfg Config) or Teardown(w io.Writer), then constructing the DoFn via NewDoFn/beam.ParDo.","commonSituations":"Trying to inject configuration or dependencies through Setup parameters instead of struct fields or initialization in the emitter/closure.","solutions":["Remove extra parameters; keep only an optional context.Context","Move configuration into exported struct fields set before pipeline construction","Perform per-bundle resource setup in StartBundle instead (with the same signature rule)"],"exampleFix":"// before\nfunc (f *MyFn) Setup(cfg Config) error { ... }\n// after\nfunc (f *MyFn) Setup(ctx context.Context) error { ... } // cfg set on struct before submit","handlingStrategy":"validation","validationCode":"m, ok := reflect.TypeOf(fn).MethodByName(\"Setup\")\nif ok {\n  t := m.Type\n  if t.NumIn() > 2 || (t.NumIn() == 2 && t.In(1) != reflect.TypeOf((*context.Context)(nil)).Elem()) {\n    return errors.New(\"Setup may only take an optional context.Context\")\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep Setup/Teardown parameter-free or ctx-only","Inject configuration via struct fields set before pipeline submission"],"tags":["go","apache-beam","dofn","lifecycle-methods"],"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"}