apache/beam · error

found emitters, want

Error message

found %v emitters, want %v

What it means

makeEmitters matches the DoFn's emit-typed parameters (FnEmit) to the output nodes of the transform. The number of emit params must equal the number of output nodes minus an offset of 1 when the function also returns a value (the single return maps to the first node). If the counts disagree, the transform cannot route emitted elements to outputs.

Solutions

  1. Match the number of outputs passed to beam.ParDo/beam.TryParDo to the number of emit parameters (or one plus the single returned value).
  2. For multi-output DoFns, declare all outputs, e.g. pos, neg := beam.ParDo2(s, &fn{}, col).
  3. If the DoFn returns a value, don't also add an emit param for the same output without an extra node.

Example fix

// before: fn has 2 emit params but only 1 output declared
out := beam.ParDo(s, &splitFn{}, col)

// after: declare both outputs
pos, neg := beam.ParDo2(s, &splitFn{}, col)
Defensive patterns

Strategy: validation

Validate before calling

emitCount := countEmitParams(fn)
retCount := countReturnValues(fn)
wantOutputs := emitCount + retCount
if actualOutputs != wantOutputs {
    return fmt.Errorf("DoFn %T declares %d outputs (emits %d, returns %d), got %d", fn, wantOutputs, emitCount, retCount, actualOutputs)
}

Prevention

When it happens

Trigger: Up() -> makeEmitters where fn.Params(FnEmit) count != len(nodes) - (1 if fn.Returns(FnValue) > 0), e.g. a DoFn with 2 emit params wired to a node with 1 output, or a DoFn that both returns a value and has emit params but only one output node.

Common situations: Adding a second emit parameter (multi-output DoFn) without adding the corresponding beam.ParDo output (must pass two PCollections / beam.Pers outputs); declaring an output in the pipeline but removing the emit param from the DoFn; mixing return-value style with emit style and miscounting nodes.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/b378bc926fa75e81. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/runtime/exec/fn.go:496

			return nil, errors.WithContextf(err, "making side input %v for %v", i, fn)
		}
		ret = append(ret, s)
	}
	return ret, nil
}

func makeEmitters(fn *funcx.Fn, nodes []Node) ([]ReusableEmitter, error) {
	if len(nodes) == 0 {
		return nil, nil // ok: no output nodes
	}

	offset := 0
	if len(fn.Returns(funcx.RetValue)) > 0 {
		offset = 1
	}
	out := fn.Params(funcx.FnEmit)
	if len(out) != len(nodes)-offset {
		return nil, errors.Errorf("found %v emitters, want %v", len(out), len(nodes)-offset)
	}

	var ret []ReusableEmitter
	for i := 0; i < len(out); i++ {
		param := fn.Param[out[i]]
		ret = append(ret, makeEmit(param.T, nodes[i+offset]))
	}
	return ret, nil
}

// makeSideInput returns a reusable side input of the given kind and type.
func makeSideInput(kind graph.InputKind, t reflect.Type, values ReStream) (ReusableInput, error) {
	switch kind {
	case graph.Singleton:
		elms, err := ReadAll(values)
		if err != nil {
			return nil, err
		}

View on GitHub (pinned to 12126d8942)