{"record":{"id":"a527305a1e201aec","repo":"apache/beam","slug":"method-v-has-invalid-return-values-only-allowed-an-optional","errorCode":null,"errorMessage":"method %v has invalid return values, only allowed an optional error","messagePattern":"method (.+?) has invalid return values, only allowed an optional error","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":597,"sourceCode":"\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) {\n\t\t\t\terr := errors.Errorf(\n\t\t\t\t\t\"method %v has invalid return values, \"+\n\t\t\t\t\t\t\"only allowed an optional error\", name)\n\t\t\t\terr = errors.SetTopLevelMsgf(err,\n\t\t\t\t\t\"Method %v of DoFns should have no return values other \"+\n\t\t\t\t\t\t\"than an optional error, but invalid return values are present \"+\n\t\t\t\t\t\t\"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 whether to perform SDF validation.\n\tisSdf, err := validateIsSdf(fn)\n\tif err != nil {\n\t\treturn nil, addContext(err, fn)\n\t}\n","sourceCodeStart":579,"sourceCodeEnd":615,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L579-L615","documentation":"Error raised in AsDoFn's post-validation: one of the lifecycle methods (Setup, StartBundle, FinishBundle, or Teardown) declares return values other than the single optional error. These lifecycle methods must return nothing or just error; any other return type on them is rejected with this message naming the offending method.","triggerScenarios":"Declaring e.g. Setup() context.Context, StartBundle() (int, error), or FinishBundle() string, then constructing the DoFn.","commonSituations":"Attempting to emit results from StartBundle/FinishBundle via return values instead of the emit function parameter on ProcessElement; returning diagnostics other than error.","solutions":["Change the method to return nothing or only error","Emit data through emit funcs on ProcessElement, not lifecycle returns","Log diagnostics instead of returning non-error values"],"exampleFix":"// before\nfunc (f *MyFn) StartBundle(ctx context.Context) int { ... }\n// after\nfunc (f *MyFn) StartBundle(ctx context.Context) error { ... }","handlingStrategy":"validation","validationCode":"for _, name := range []string{\"Setup\", \"StartBundle\", \"FinishBundle\", \"Teardown\"} {\n  m, ok := reflect.TypeOf(fn).MethodByName(name)\n  if !ok { continue }\n  t := m.Type\n  if t.NumOut() > 1 || (t.NumOut() == 1 && t.Out(0) != reflect.TypeOf((*error)(nil)).Elem()) {\n    return fmt.Errorf(\"%s must return nothing or error\", name)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Return only error (or nothing) from lifecycle methods","Never use lifecycle returns to pass data downstream"],"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"}