apache/beam · error

Flatten needs at least 2 input, got

Error message

Flatten needs at least 2 input, got %v

What it means

NewFlatten requires at least two input nodes because Flatten merges multiple PCollections into one; a single input makes the edge meaningless. The Beam Go graph builder throws this when TryFlatten/beam.Flatten is invoked with fewer than 2 inputs. It is a fail-fast arity check during graph construction.

Solutions

  1. Ensure at least two PCollections are passed to beam.Flatten.
  2. Guard the call: if len(inputs) < 2, use the single PCollection directly instead of Flatten.
  3. If inputs are dynamic, handle the 0- and 1-element cases before calling Flatten.
  4. Pass beam.Create(s) of an empty list as a second input only if a genuine empty merge is required.

Example fix

// before
merged := beam.Flatten(s, inputs...) // inputs has only 1 element
// after
var merged beam.PCollection
if len(inputs) < 2 {
    merged = inputs[0]
} else {
    merged = beam.Flatten(s, inputs...)
}
Defensive patterns

Strategy: validation

Validate before calling

// Go: guard dynamic input lists before Flatten
if len(inputs) == 0 {
    merged = beam.Create(s)
} else if len(inputs) == 1 {
    merged = inputs[0]
} else {
    merged = beam.Flatten(s, inputs...)
}

Prevention

When it happens

Trigger: Calling beam.Flatten with exactly one PCollection (or an empty slice after filtering), e.g. `beam.Flatten(s, pc)` or `beam.Flatten(s)`.

Common situations: Dynamically building input lists where conditionals filtered out all but one PCollection; generated pipelines where a variable-length list degenerated to one element.

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/46a56bbea991f193. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/graph/edge.go:259

	edge := g.NewEdge(s)
	edge.Op = CoGBK
	for i := 0; i < len(ns); i++ {
		edge.Input = append(edge.Input, &Inbound{Kind: Main, From: ns[i], Type: ns[i].Type()})
	}
	edge.Output = []*Outbound{{To: out, Type: t}}
	return edge, nil
}

// NewFlatten inserts a new Flatten edge in the graph. Flatten output type is
// the shared input type.
func NewFlatten(g *Graph, s *Scope, in []*Node) (*MultiEdge, error) {
	addContext := func(err error, s *Scope) error {
		return errors.WithContextf(err, "creating new Flatten in scope %v", s)
	}

	if len(in) < 2 {
		return nil, addContext(errors.Errorf("Flatten needs at least 2 input, got %v", len(in)), s)
	}
	t := in[0].Type()
	w := inputWindow(in)

	// TODO(herohde) 4/5/2018: is it fine mixing boundedness for flatten?
	// The output would be unbounded iff any input is.
	bounded := true
	for _, n := range in {
		if !n.Bounded() {
			bounded = false
			break
		}
	}
	for _, n := range in {
		if !typex.IsEqual(t, n.Type()) {
			return nil, addContext(errors.Errorf("mismatched Flatten input types: %v, want %v", n.Type(), t), s)
		}
		if !w.Equals(n.WindowingStrategy()) {

View on GitHub (pinned to 12126d8942)