apache/beam · error
first main input parameter must be a value type
Error message
first main input parameter must be a value type
What it means
When validating a DoFn (AsDoFn -> validateMainInputs), Beam requires the first main input parameter of ProcessElement to be a plain value (FnValue). Iterators (Iter) or re-iterators (ReIter) cannot be the first main input because the framework must hand the element itself before any iterable view.
Source
Thrown at sdks/go/pkg/beam/core/graph/fn.go:680
err = errors.SetTopLevelMsgf(err,
"Method %v in DoFn %v is missing all inputs. A main input is required.",
methodName, fn.Name())
return err
}
if num < int(numMainIn) {
err := errors.Errorf("%v method has too few main inputs", methodName)
err = errors.SetTopLevelMsgf(err,
"Method %v in DoFn %v does not have enough main inputs. "+
"%v main inputs were expected, but only %v inputs were found.",
methodName, fn.Name(), numMainIn, num)
return err
}
// Check that the first input is not an Iter or ReIter (those aren't valid
// as the first main input).
first := method.Param[pos].Kind
if first != funcx.FnValue {
err := errors.New("first main input parameter must be a value type")
err = errors.SetTopLevelMsgf(err,
"Method %v of DoFns should always have the first input be a value type, "+
"but it has an Iter or ReIter first in DoFn %v.",
processElementName, fn.Name())
return errors.WithContextf(err, "method %v", processElementName)
}
return nil
}
// validateEmits compares the emits found in a DoFn method signature with the emits found in
// the signature for ProcessElement, and performs validation that those match. This function
// should only be used to validate methods that are expected to have the same emit parameters as
// ProcessElement.
func validateEmits(processFnEmits []funcx.FnParam, method *funcx.Fn, methodName string) error {
posMethodEmits, numMethodEmits, ok := method.Emits()
numProcessEmits := len(processFnEmits)
// Handle cases where method has no emits.View on GitHub (pinned to 12126d8942)
Solutions
- Reorder ProcessElement parameters so a value-typed element comes first; put Iter/ReIter parameters after it.
- If the intent is full-group iteration, use a value parameter of a slice/KV type instead of an Iter as the first input.
- For GBK results, accept the CoGBK result type properly (KV<K, Iter<V>>) rather than a bare Iter main input.
- Use a side input if the iterable is a side view rather than a main input.
Example fix
// before
func (fn *f) ProcessElement(it func(func(int) bool), k string) {}
// after
func (fn *f) ProcessElement(k string, it func(func(int) bool)) {} Defensive patterns
Strategy: validation
Validate before calling
func firstMainInputIsValue(fn reflect.Type, skip int) bool {
return fn.In(skip).Kind() != reflect.Ptr || reflect.TypeOf(typex.EventTime(0)) != fn.In(skip).Elem()
} Prevention
- Always place the element value first in ProcessElement; iterators come after.
- Use CoGBK result types (KV<K, Iter<V>>) for whole-group processing instead of bare Iter first inputs.
- Run graph-construction tests that invoke AsDoFn on all DoFns before deploying.
When it happens
Trigger: Declaring ProcessElement with an iterator parameter before the element, e.g. `ProcessElement(iter func(func(int) bool), v string)` where both are main inputs, or restructuring signatures so an Iter/ReIter precedes the element value.
Common situations: DoFns adapted from group-by-key patterns where whole-group iteration was intended but written as the first main input; porting from other SDKs where element iteration order is flexible.
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
- too many return values: %v
- ProcessElement doesn't use a TimerProvider, but Timer field
- ProcessElement uses a TimerProvider, but no Timer fields are
- bad parameter type for %s: %v
- not enough required parameters: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/cab4573ac3504ca9.
Report an issue: GitHub.