apache/beam · error

mismatched Flatten input types

Error message

mismatched Flatten input types: %v, want %v

What it means

NewFlatten checks that every input node's type equals the type of the first input (`typex.IsEqual`). Flatten can only merge PCollections of the same element type, so mismatched input types abort graph construction with this error. The message reports the offending node's type and the expected type taken from in[0].

Solutions

  1. Make all flattened inputs share the same element type; insert a map/ParDo to convert elements to a common type first.
  2. Define a common struct or use beam.KV for heterogeneous records and convert each branch before flattening.
  3. Verify which input is in[0] (its type is the expected one) and align the others to it.
  4. Check encoders/coder registration if using custom types so types resolve identically.

Example fix

// before
merged := beam.Flatten(s, stringsPC, intsPC) // type mismatch
// after
asStrings := beam.ParDo(s, func(i int) string { return strconv.Itoa(i) }, intsPC)
merged := beam.Flatten(s, stringsPC, asStrings)
Defensive patterns

Strategy: validation

Validate before calling

// Go: compare element types before Flatten (conceptual)
// Ensure every branch's ParDo/transform declares the same output type T as the first input.

Prevention

When it happens

Trigger: Calling beam.Flatten(s, pcA, pcB) where pcA and pcB have different full types, e.g. PCollection<string> and PCollection<int>, or structurally different types like KV<K,V> vs a custom struct.

Common situations: Merging outputs of different DoFns that emit different types; accidentally flattening a KV collection with a raw-value collection; type changes after a ParDo with mismatched Emit type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

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

	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()) {
			return nil, addContext(errors.Errorf("mismatched Flatten window types: %v, want %v", n.WindowingStrategy(), w), s)
		}
	}
	if typex.IsCoGBK(t) {
		return nil, addContext(errors.Errorf("Flatten input type cannot be CoGBK: %v", t), s)
	}

	edge := g.NewEdge(s)
	edge.Op = Flatten
	for _, n := range in {
		edge.Input = append(edge.Input, &Inbound{Kind: Main, From: n, Type: t})
	}
	edge.Output = []*Outbound{{To: g.NewNode(t, w, bounded), Type: t}}
	return edge, nil
}

View on GitHub (pinned to 12126d8942)