{"record":{"id":"1b5c1c6c60f52a25","repo":"apache/beam","slug":"mismatched-flatten-input-types-v-want-v","errorCode":null,"errorMessage":"mismatched Flatten input types: %v, want %v","messagePattern":"mismatched Flatten input types: (.+?), want (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/edge.go","lineNumber":275,"sourceCode":"\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()) {\n\t\t\treturn nil, addContext(errors.Errorf(\"mismatched Flatten window types: %v, want %v\", n.WindowingStrategy(), w), s)\n\t\t}\n\t}\n\tif typex.IsCoGBK(t) {\n\t\treturn nil, addContext(errors.Errorf(\"Flatten input type cannot be CoGBK: %v\", t), s)\n\t}\n\n\tedge := g.NewEdge(s)\n\tedge.Op = Flatten\n\tfor _, n := range in {\n\t\tedge.Input = append(edge.Input, &Inbound{Kind: Main, From: n, Type: t})\n\t}\n\tedge.Output = []*Outbound{{To: g.NewNode(t, w, bounded), Type: t}}\n\treturn edge, nil\n}\n","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/edge.go#L257-L293","documentation":"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].","triggerScenarios":"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.","commonSituations":"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.","solutions":["Make all flattened inputs share the same element type; insert a map/ParDo to convert elements to a common type first.","Define a common struct or use beam.KV for heterogeneous records and convert each branch before flattening.","Verify which input is in[0] (its type is the expected one) and align the others to it.","Check encoders/coder registration if using custom types so types resolve identically."],"exampleFix":"// before\nmerged := beam.Flatten(s, stringsPC, intsPC) // type mismatch\n// after\nasStrings := beam.ParDo(s, func(i int) string { return strconv.Itoa(i) }, intsPC)\nmerged := beam.Flatten(s, stringsPC, asStrings)","handlingStrategy":"validation","validationCode":"// Go: compare element types before Flatten (conceptual)\n// Ensure every branch's ParDo/transform declares the same output type T as the first input.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize branch outputs on one named Go type or beam.KV before merging.","Convert heterogeneous records with an explicit ParDo mapping to a common struct.","Check each branch's emit type when refactoring DoFns."],"tags":["beam-go","flatten","type-mismatch","graph-construction"],"backgroundTag":"type-mismatch","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"}