apache/beam · error
method has invalid parameters, only allowed an optional…
Error message
method %v has invalid parameters, only allowed an optional context.Context
What it means
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.
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)
Example fix
// before
func (f *MyFn) Setup(cfg Config) error { ... }
// after
func (f *MyFn) Setup(ctx context.Context) error { ... } // cfg set on struct before submit Defensive patterns
Strategy: validation
Validate before calling
m, ok := reflect.TypeOf(fn).MethodByName("Setup")
if ok {
t := m.Type
if t.NumIn() > 2 || (t.NumIn() == 2 && t.In(1) != reflect.TypeOf((*context.Context)(nil)).Elem()) {
return errors.New("Setup may only take an optional context.Context")
}
} Prevention
- Keep Setup/Teardown parameter-free or ctx-only
- Inject configuration via struct fields set before pipeline submission
When it happens
Trigger: 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.
Common situations: Trying to inject configuration or dependencies through Setup parameters instead of struct fields or initialization in the emitter/closure.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- method has invalid return values, only allowed an optional…
- Duplicate state key used by and . Ensure that state keys…
- emit parameter in method
- emit parameters expected in method
- error writing state
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/2b95f6f28594eed3.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/graph/fn.go:578
processFnEmits = processFn.Param[0:0]
}
if startFn, ok := fn.methods[startBundleName]; ok {
if err := validateEmits(processFnEmits, startFn, startBundleName); err != nil {
return nil, addContext(err, fn)
}
}
if finishFn, ok := fn.methods[finishBundleName]; ok {
if err := validateEmits(processFnEmits, finishFn, finishBundleName); err != nil {
return nil, addContext(err, fn)
}
}
// Check that Setup and Teardown have no parameters other than Context.
for _, name := range []string{setupName, teardownName} {
if method, ok := fn.methods[name]; ok {
params := method.Param
if len(params) > 1 || (len(params) == 1 && params[0].Kind != funcx.FnContext) {
err := errors.Errorf(
"method %v has invalid parameters, "+
"only allowed an optional context.Context", name)
err = errors.SetTopLevelMsgf(err,
"Method %v of DoFns should have no parameters other than "+
"an optional context.Context, but invalid parameters are "+
"present in DoFn %v.",
name, fn.Name())
return nil, addContext(err, fn)
}
}
}
// Check that none of the methods (except ProcessElement) have any return
// values other than error.
for _, name := range []string{setupName, startBundleName, finishBundleName, teardownName} {
if method, ok := fn.methods[name]; ok {
returns := method.Ret
if len(returns) > 1 || (len(returns) == 1 && returns[0].Kind != funcx.RetError) {View on GitHub (pinned to 12126d8942)