apache/beam · critical

KV coder with more than 2 components: %s

Error message

KV coder with more than 2 components: %s

What it means

The prism runner builds pull-based decoders for pipeline coders. A KV coder must have exactly two component coders (key and value); this panic fires when the pipeline harness hands prism a KV coder whose component list has any other length, meaning the coder graph sent by the SDK is malformed.

Source

Thrown at sdks/go/pkg/beam/runners/prism/internal/coders.go:351

		return func(r io.Reader) {
			coder.DecodeDouble(r)
		}
	case urns.CoderIterable:
		ccids := c.GetComponentCoderIds()
		if len(ccids) != 1 {
			panic(fmt.Sprintf("Iterable coder must have only one component: %s", prototext.Format(c)))
		}
		ed := pullDecoderNoAlloc(coders[ccids[0]], coders)
		return func(r io.Reader) {
			l, _ := coder.DecodeInt32(r)
			for i := int32(0); i < l; i++ {
				ed(r)
			}
		}
	case urns.CoderKV:
		ccids := c.GetComponentCoderIds()
		if len(ccids) != 2 {
			panic(fmt.Sprintf("KV coder with more than 2 components: %s", prototext.Format(c)))
		}
		kd := pullDecoderNoAlloc(coders[ccids[0]], coders)
		vd := pullDecoderNoAlloc(coders[ccids[1]], coders)
		return func(r io.Reader) {
			kd(r)
			vd(r)
		}
	case urns.CoderWindowedValue:
		ccids := c.GetComponentCoderIds()
		if len(ccids) != 2 {
			panic(fmt.Sprintf("WindowedValue coder with more than 2 components: %s", prototext.Format(c)))
		}
		ed := pullDecoderNoAlloc(coders[ccids[0]], coders)
		wd := pullDecoderNoAlloc(coders[ccids[1]], coders)
		return func(r io.Reader) {
			ed(r)
			wd(r)
		}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Inspect the coder proto in the panic message (prototext format) and check the component_coder_ids count
  2. Verify SDK and prism runner versions match (use the same Beam release on both sides)
  3. Reproduce with a minimal pipeline to identify the transform producing the bad coder
  4. File/inspect a Beam issue if the SDK legitimately emitted a malformed KV coder

Example fix

// before: constructing a KV coder manually with wrong components
coder := pipepb.Coder{Spec: ...} // components omitted
// after: ensure exactly 2 component coder IDs are set
if len(kvCoder.GetComponentCoderIds()) != 2 { /* fix coder construction */ }
Defensive patterns

Strategy: validation

Validate before calling

if len(kvCoder.GetComponentCoderIds()) != 2 { return fmt.Errorf("KV coder must have exactly 2 components, got %d", len(kvCoder.GetComponentCoderIds())) }

Try / catch

// panics are not recoverable at this layer; recover only at the harness boundary
defer func() { if r := recover(); r != nil { log.Errorf("coder setup panicked: %v", r) } }()

Prevention

When it happens

Trigger: pullDecoderNoAlloc encounters a proto coder with urn beam:coders:kv:v1 whose GetComponentCoderIds() returns != 2, e.g. a KV coder referencing zero, one, or three+ component coder IDs, typically due to a corrupted or hand-edited pipeline proto or an SDK-side coder-construction bug.

Common situations: Running pipelines cross-language where one SDK emits a malformed KV coder; SDK/runner version skew where coder representation changed; custom DoFns or coders that assemble KV coders programmatically with the wrong number of components.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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