apache/beam · error
number of emits in method %v does not match method %v: got %
Error message
number of emits in method %v does not match method %v: got %d, expected %d
What it means
Apache Beam Go validates optional DoFn methods (e.g. StartBundle, FinishBundle, Setup, Teardown) against ProcessElement. When such a method declares emit (PCollection output) parameters, their count must exactly match the number of emits in ProcessElement. This error is thrown by validateEmits, called from AsDoFn during graph construction, when the counts differ.
Source
Thrown at sdks/go/pkg/beam/core/graph/fn.go:713
posMethodEmits, numMethodEmits, ok := method.Emits()
numProcessEmits := len(processFnEmits)
// Handle cases where method has no emits.
if !ok {
if numProcessEmits == 0 { // We're good, expected no emits.
return nil
}
// Error, missing emits.
err := errors.Errorf("emit parameters expected in method %v", methodName)
return errors.SetTopLevelMsgf(err,
"Missing emit parameters in the %v method of a DoFn. "+
"If emit parameters are present in %v those parameters must also be present in %v.",
methodName, processElementName, methodName)
}
// Error if number of emits doesn't match.
if numMethodEmits != numProcessEmits {
err := errors.Errorf("number of emits in method %v does not match method %v: got %d, expected %d",
methodName, processElementName, numMethodEmits, numProcessEmits)
return errors.SetTopLevelMsgf(err,
"Incorrect number of emit parameters in the %v method of a DoFn. "+
"The emit parameters should match those of the %v method.",
methodName, processElementName)
}
// Error if there's a type mismatch.
methodEmits := method.Param[posMethodEmits : posMethodEmits+numMethodEmits]
for i := 0; i < numProcessEmits; i++ {
if processFnEmits[i].T != methodEmits[i].T {
var err error = &funcx.TypeMismatchError{Got: methodEmits[i].T, Want: processFnEmits[i].T}
err = errors.Wrapf(err, "emit parameter in method %v does not match emit parameter in %v",
methodName, processElementName)
return errors.SetTopLevelMsgf(err,
"Incorrect emit parameters in the %v method of a DoFn. "+
"The emit parameters should match those of the %v method.",
methodName, processElementName)View on GitHub (pinned to 12126d8942)
Solutions
- Add or remove emit parameters in the auxiliary method so its emit count matches ProcessElement.
- If the method does not need to emit, remove all emit parameters from it.
- Use the same emitter types (funcx.OutputT / beam emitter types) as in ProcessElement to also satisfy the follow-up type check (error 4901).
Example fix
// before
func (fn *myFn) ProcessElement(ctx context.Context, w string, emit1, emit2 func(int)) {}
func (fn *myFn) FinishBundle(emit func(int)) {}
// after
func (fn *myFn) ProcessElement(ctx context.Context, w string, emit1, emit2 func(int)) {}
func (fn *myFn) FinishBundle(emit1, emit2 func(int)) {} Defensive patterns
Strategy: validation
Validate before calling
pe := reflect.TypeOf(fn).Method; // compare emitter counts across DoFn methods before beam.ParDo
// simplest: keep emit parameters only in ProcessElement unless all methods mirror them exactly
if !dofnEmitsMatch(fn) {
return fmt.Errorf("emit counts must match across DoFn methods")
} Type guard
func hasEmits(m reflect.Method) bool { _, ok := m.Type.In(m.Type.NumIn()-1).(interface{}); return ok } // inspect last params for func(...) emitters Try / catch
err := beam.ParDo(s, &myFn{}, in); if err != nil {
var top = errors.UnwrapTop(err)
log.Fatalf("DoFn emit signature invalid: %v", top)
} Prevention
- Mirror emitter parameters across all DoFn methods by copy-pasting from ProcessElement
- Run pipeline construction in a fast unit test before deployment
- Avoid declaring emitters in StartBundle/FinishBundle unless actively emitting there
When it happens
Trigger: Registering a DoFn whose StartBundle/FinishBundle/Setup/Teardown method declares a different number of emit parameters than ProcessElement, then calling beam.ParDo / beam.DoFn conversion (AsDoFn) via beam.ParDo(s, fn, input) when building a pipeline.
Common situations: Adding a new output PCollection to ProcessElement but forgetting to add the matching emitter to StartBundle/FinishBundle; copy-pasting a DoFn and editing only ProcessElement; refactoring output counts without updating auxiliary methods.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- emit parameter in method %v does not match emit parameter in
- side inputs expected in method %v
- number of side inputs in method %v does not match method %v:
- number of side inputs in method %v does not match method %v:
- ProcessElement doesn't use a StateProvider, but State struct
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/bd9c4d705134e8c0.
Report an issue: GitHub.