apache/beam · error
multimap side inputs needs KV coder, got
Error message
multimap side inputs needs KV coder, got %v
What it means
Multimap side inputs require the input PCollection to be a KV pair so keys can be mapped to lists of values. If the coder's URN is not beam:coder:kv, handleSideInput rejects the access pattern with this error, naming the actual URN found.
Solutions
- Ensure the side input PCollection is a KV collection (beam.KV) before using a multimap view
- Use beam.AsMap (single-map) instead of multimap view if elements are not KV
- Check that upstream ParDo outputs KV-coded PCollections
- Inspect the reported URN in the message to confirm the coder type mismatch
Example fix
// before
si := beam.SideInput(pcoll) // pcoll is of type T, not KV
// after
kvPcol := beam.ParDo(p, func(t T) (K, V) {...}, input)
si := beam.SideInput(kvPcol) // KV coder required for multimap Defensive patterns
Strategy: type-guard
Validate before calling
// Before using a multimap side input, assert KV typing
coderURN := coderURNOf(sideInputPcol)
if coderURN != "beam:coder:kv:v1" {
return fmt.Errorf("multimap side input requires KV, got %s", coderURN)
} Type guard
func isKVCoder(c *pipepb.Coder) bool {
return c.GetSpec().GetUrn() == "beam:coder:kv:v1"
} Prevention
- Always build side inputs from KV-typed PCollections for multimap views
- Use beam.Kv explicitly when in doubt
- Prefer AsMap for non-KV collections
When it happens
Trigger: A pipeline uses a multimap side input access pattern while the side input PCollection's coder is not a KV coder (e.g. a plain element coder, or an iterable/window coder instead of KV).
Common situations: Using beam.AsMap or multimap views over non-K<->V collections; forgetting beam.KV for side input elements; SDK constructs emitting windowed values instead of KV.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- buildDescriptor: failed to handle coder on stage
- local input (global ) uses accesspattern
- stage[ ] no parent for side input , with parent ID
- stage[ ] no parent ID for side input
- buildDescriptor: couldn't retrieve coder
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/63169eabc392b191.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/runners/prism/internal/stage.go:734
if b.IterableSideInputData == nil {
b.IterableSideInputData = map[worker.SideInputKey]map[typex.Window][][]byte{}
}
b.IterableSideInputData[worker.SideInputKey{
TransformID: link.Transform,
Local: link.Local,
}] = data
}, nil
case urns.SideInputMultiMap:
slog.Debug("urnSideInputMultiMap",
slog.String("sourceTransform", t.GetUniqueName()),
slog.String("local", link.Local),
slog.String("global", link.Global))
col := pcols[link.Global]
kvc := comps.GetCoders()[col.GetCoderId()]
if kvc.GetSpec().GetUrn() != urns.CoderKV {
return nil, fmt.Errorf("multimap side inputs needs KV coder, got %v", kvc.GetSpec().GetUrn())
}
kd := collectionPullDecoder(kvc.GetComponentCoderIds()[0], coders, comps)
vd := collectionPullDecoder(kvc.GetComponentCoderIds()[1], coders, comps)
// The returned coders are unused here, but they add the side input coders
// to the stage components for use SDK side.
getWindowValueCoders(comps, col, coders)
return func(b *worker.B, watermark mtime.Time) {
// May be of zero length, but that's OK. Side inputs can be empty.
data := em.GetSideData(b.PBDID, link.Transform, link.Local, watermark)
if b.MultiMapSideInputData == nil {
b.MultiMapSideInputData = map[worker.SideInputKey]map[typex.Window]map[string][][]byte{}
}
windowed := map[typex.Window]map[string][][]byte{}
for win, ds := range data {
if len(ds) == 0 {View on GitHub (pinned to 12126d8942)