{"record":{"id":"46a56bbea991f193","repo":"apache/beam","slug":"flatten-needs-at-least-2-input-got-v","errorCode":null,"errorMessage":"Flatten needs at least 2 input, got %v","messagePattern":"Flatten needs at least 2 input, got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/edge.go","lineNumber":259,"sourceCode":"\n\tedge := g.NewEdge(s)\n\tedge.Op = CoGBK\n\tfor i := 0; i < len(ns); i++ {\n\t\tedge.Input = append(edge.Input, &Inbound{Kind: Main, From: ns[i], Type: ns[i].Type()})\n\t}\n\tedge.Output = []*Outbound{{To: out, Type: t}}\n\treturn edge, nil\n}\n\n// NewFlatten inserts a new Flatten edge in the graph. Flatten output type is\n// the shared input type.\nfunc NewFlatten(g *Graph, s *Scope, in []*Node) (*MultiEdge, error) {\n\taddContext := func(err error, s *Scope) error {\n\t\treturn errors.WithContextf(err, \"creating new Flatten in scope %v\", s)\n\t}\n\n\tif len(in) < 2 {\n\t\treturn nil, addContext(errors.Errorf(\"Flatten needs at least 2 input, got %v\", len(in)), s)\n\t}\n\tt := in[0].Type()\n\tw := inputWindow(in)\n\n\t// TODO(herohde) 4/5/2018: is it fine mixing boundedness for flatten?\n\t// The output would be unbounded iff any input is.\n\tbounded := true\n\tfor _, n := range in {\n\t\tif !n.Bounded() {\n\t\t\tbounded = false\n\t\t\tbreak\n\t\t}\n\t}\n\tfor _, n := range in {\n\t\tif !typex.IsEqual(t, n.Type()) {\n\t\t\treturn nil, addContext(errors.Errorf(\"mismatched Flatten input types: %v, want %v\", n.Type(), t), s)\n\t\t}\n\t\tif !w.Equals(n.WindowingStrategy()) {","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/edge.go#L241-L277","documentation":"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.","triggerScenarios":"Calling beam.Flatten with exactly one PCollection (or an empty slice after filtering), e.g. `beam.Flatten(s, pc)` or `beam.Flatten(s)`.","commonSituations":"Dynamically building input lists where conditionals filtered out all but one PCollection; generated pipelines where a variable-length list degenerated to one element.","solutions":["Ensure at least two PCollections are passed to beam.Flatten.","Guard the call: if len(inputs) < 2, use the single PCollection directly instead of Flatten.","If inputs are dynamic, handle the 0- and 1-element cases before calling Flatten.","Pass beam.Create(s) of an empty list as a second input only if a genuine empty merge is required."],"exampleFix":"// before\nmerged := beam.Flatten(s, inputs...) // inputs has only 1 element\n// after\nvar merged beam.PCollection\nif len(inputs) < 2 {\n    merged = inputs[0]\n} else {\n    merged = beam.Flatten(s, inputs...)\n}","handlingStrategy":"validation","validationCode":"// Go: guard dynamic input lists before Flatten\nif len(inputs) == 0 {\n    merged = beam.Create(s)\n} else if len(inputs) == 1 {\n    merged = inputs[0]\n} else {\n    merged = beam.Flatten(s, inputs...)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always handle the 0- and 1-element cases when building Flatten input lists dynamically.","Avoid filtering the slice of PCollections right before Flatten without re-checking its length."],"tags":["beam-go","flatten","arity","graph-construction"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}