{"record":{"id":"7440e78465182ed6","repo":"apache/beam","slug":"needs-at-least-1-input","errorCode":null,"errorMessage":"needs at least 1 input","messagePattern":"needs at least 1 input","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/edge.go","lineNumber":206,"sourceCode":"\treturn e.parent\n}\n\nfunc (e *MultiEdge) String() string {\n\treturn fmt.Sprintf(\"%v: %v %v -> %v\", e.id, e.Op, e.Input, e.Output)\n}\n\n// NOTE(herohde) 4/28/2017: In general, we have no good coder guess for outgoing\n// nodes, unless we add a notion of default coder for arbitrary types. We leave\n// that to the beam layer.\n\n// NewCoGBK inserts a new CoGBK edge into the graph.\nfunc NewCoGBK(g *Graph, s *Scope, ns []*Node) (*MultiEdge, error) {\n\taddContext := func(err error, s *Scope) error {\n\t\treturn errors.WithContextf(err, \"creating new CoGBK in scope %v\", s)\n\t}\n\n\tif len(ns) == 0 {\n\t\treturn nil, addContext(errors.New(\"needs at least 1 input\"), s)\n\t}\n\tif !typex.IsKV(ns[0].Type()) {\n\t\treturn nil, addContext(errors.Errorf(\"input type must be KV: %v\", ns[0]), s)\n\t}\n\n\t// (1) Create CoGBK result type: KV<T,U>, .., KV<T,Z> -> CoGBK<T,U,..,Z>.\n\n\tc := ns[0].Coder.Components[0]\n\tw := inputWindow(ns)\n\tbounded := inputBounded(ns)\n\tcomp := []typex.FullType{c.T, ns[0].Type().Components()[1]}\n\n\tfor i := 1; i < len(ns); i++ {\n\t\tn := ns[i]\n\t\tif !typex.IsKV(n.Type()) {\n\t\t\treturn nil, addContext(errors.Errorf(\"input type must be KV: %v\", n), s)\n\t\t}\n\t\tif !n.Coder.Components[0].Equals(c) {","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/edge.go#L188-L224","documentation":"NewCoGBK builds a CoGroupByKey multi-edge in the graph and requires at least one input node. Called with an empty node slice it fails immediately; additionally the first input must be a KV type since CoGBK groups by key.","triggerScenarios":"Calling graph.NewCoGBK (via beam.CoGroupByKey/TryCoGroupByKey) with zero PCollections, e.g. from an empty slice of inputs, or passing a non-KV PCollection as the first node.","commonSituations":"Programmatically building CoGBK from a dynamically collected list of PCollections that ended up empty (e.g. empty map/slice iteration, filtered-out inputs), or forgetting to convert values to KV before grouping.","solutions":["Ensure at least one KV-typed PCollection is passed to CoGroupByKey before calling it.","Guard the call site: skip the CoGBK (or error out earlier) when the input slice is empty.","Convert inputs with beam.KV(s, k, v) / MakeKV so the first node type is KV.","Check upstream code that assembles the input list (loops, filters) for logic that drains it."],"exampleFix":"// before\nif len(pcolls) == 0 { /* falls through */ }\nres := beam.CoGroupByKey(s, pcolls...)\n// after\nif len(pcolls) == 0 {\n    return errors.New(\"CoGroupByKey needs at least one KV PCollection\")\n}\nres := beam.CoGroupByKey(s, pcolls...)","handlingStrategy":"validation","validationCode":"if len(inputs) == 0 {\n    return errors.New(\"CoGroupByKey requires at least one KV PCollection\")\n}\nif !typex.IsKV(inputs[0].Type()) {\n    return errors.New(\"first CoGroupByKey input must be KV-typed\")\n}","typeGuard":"func isKV(n *graph.Node) bool { return typex.IsKV(n.Type()) }","tryCatchPattern":null,"preventionTips":["Guard dynamic input lists before calling CoGroupByKey.","Convert collections to KV pairs (beam.KV) before grouping.","Add pipeline-construction unit tests that build graphs with edge-case input counts."],"tags":["go","beam","graph","cogroupbykey"],"backgroundTag":"empty-required-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}