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
- Inspect the coder proto in the panic message (prototext format) and check the component_coder_ids count
- Verify SDK and prism runner versions match (use the same Beam release on both sides)
- Reproduce with a minimal pipeline to identify the transform producing the bad coder
- 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
- Use stock Beam SDK coder constructors instead of hand-building coder protos
- Keep SDK and prism runner versions identical
- Validate coder protos in custom tooling before submitting pipelines
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
- WindowedValue coder with more than 2 components: %s
- ShardedKey coder must have only 1 component: %s
- Runner forgot to LP this Row Coder. %v
- unknown coder urn key: %v
- %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/cf38be4c7797bc92.
Report an issue: GitHub.