apache/beam · error

needs at least 1 input

Error message

needs at least 1 input

What it means

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.

Source

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

	return e.parent
}

func (e *MultiEdge) String() string {
	return fmt.Sprintf("%v: %v %v -> %v", e.id, e.Op, e.Input, e.Output)
}

// NOTE(herohde) 4/28/2017: In general, we have no good coder guess for outgoing
// nodes, unless we add a notion of default coder for arbitrary types. We leave
// that to the beam layer.

// NewCoGBK inserts a new CoGBK edge into the graph.
func NewCoGBK(g *Graph, s *Scope, ns []*Node) (*MultiEdge, error) {
	addContext := func(err error, s *Scope) error {
		return errors.WithContextf(err, "creating new CoGBK in scope %v", s)
	}

	if len(ns) == 0 {
		return nil, addContext(errors.New("needs at least 1 input"), s)
	}
	if !typex.IsKV(ns[0].Type()) {
		return nil, addContext(errors.Errorf("input type must be KV: %v", ns[0]), s)
	}

	// (1) Create CoGBK result type: KV<T,U>, .., KV<T,Z> -> CoGBK<T,U,..,Z>.

	c := ns[0].Coder.Components[0]
	w := inputWindow(ns)
	bounded := inputBounded(ns)
	comp := []typex.FullType{c.T, ns[0].Type().Components()[1]}

	for i := 1; i < len(ns); i++ {
		n := ns[i]
		if !typex.IsKV(n.Type()) {
			return nil, addContext(errors.Errorf("input type must be KV: %v", n), s)
		}
		if !n.Coder.Components[0].Equals(c) {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure at least one KV-typed PCollection is passed to CoGroupByKey before calling it.
  2. Guard the call site: skip the CoGBK (or error out earlier) when the input slice is empty.
  3. Convert inputs with beam.KV(s, k, v) / MakeKV so the first node type is KV.
  4. Check upstream code that assembles the input list (loops, filters) for logic that drains it.

Example fix

// before
if len(pcolls) == 0 { /* falls through */ }
res := beam.CoGroupByKey(s, pcolls...)
// after
if len(pcolls) == 0 {
    return errors.New("CoGroupByKey needs at least one KV PCollection")
}
res := beam.CoGroupByKey(s, pcolls...)
Defensive patterns

Strategy: validation

Validate before calling

if len(inputs) == 0 {
    return errors.New("CoGroupByKey requires at least one KV PCollection")
}
if !typex.IsKV(inputs[0].Type()) {
    return errors.New("first CoGroupByKey input must be KV-typed")
}

Type guard

func isKV(n *graph.Node) bool { return typex.IsKV(n.Type()) }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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