{"record":{"id":"2d8fa02c11fe8f7c","repo":"apache/beam","slug":"cannot-make-a-keyed-iterable-for-an-unkeyed-side-input-v","errorCode":null,"errorMessage":"cannot make a keyed iterable for an unkeyed side input %v","messagePattern":"cannot make a keyed iterable for an unkeyed side input (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/exec/sideinput.go","lineNumber":109,"sourceCode":"\n\t// Cache miss, build new ReStream\n\tr := &proxyReStream{\n\t\topen: func() (Stream, error) {\n\t\t\tr, err := reader.OpenIterableSideInput(ctx, s.sid, s.sideInputID, win)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &elementStream{r: r, ec: s.ec}, nil\n\t\t},\n\t}\n\treturn cache.SetCache(ctx, s.sid.PtransformID, s.sideInputID, win, key, r), nil\n}\n\n// NewKeyedIterable returns a ReStream of a multimap side input from the runner, either by getting the ReStream from\n// the side input cache or by opening a new stream and reading it in.\nfunc (s *sideInputAdapter) NewKeyedIterable(ctx context.Context, reader StateReader, w typex.Window, iterKey any) (ReStream, error) {\n\tif s.kc == nil {\n\t\treturn nil, fmt.Errorf(\"cannot make a keyed iterable for an unkeyed side input %v\", s.sideInputID)\n\t}\n\tkey, err := EncodeElement(s.kc, iterKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmw, err := s.wm.MapWindow(w)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\twin, err := EncodeWindow(s.wc, mw)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcache := reader.GetSideInputCache()\n\t// Cache hit\n\tif r := cache.QueryCache(ctx, s.sid.PtransformID, s.sideInputID, win, key); r != nil {\n\t\treturn r, nil\n\t}","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/exec/sideinput.go#L91-L127","documentation":"sideInputAdapter.NewKeyedIterable builds a ReStream for a multimap (keyed) side input. It requires a key coder (kc); if the side input was registered as unkeyed (single-iteration side input), keyed access is impossible and this error names the offending side input ID. It flags a mismatch between how the side input was declared and how it is consumed.","triggerScenarios":"Calling NewKeyedIterable for a side input whose adapter was created without a key coder — i.e. accessing an Iterable side input as if it were a Map/Multimap side input.","commonSituations":"Pipeline declares a plain side input (beam.SideInput of an unordered/iterable PCollection) but the transform accesses it keyed (e.g. via a multimap view); translation emits wrong access info; custom runners calling the adapter directly with wrong iterKey.","solutions":["Declare the side input as a keyed/multimap view (e.g. use beam.Combine_perKey or CoGBK-style keyed access) if keyed lookup is intended.","If plain iteration is intended, access the side input through the non-keyed path (NewIterable) instead.","Check the side input's access/type info in the pipeline proto (side input ID %v) matches the consumer's expectation.","Ensure both producing and consuming transforms were built with consistent Beam version/view types."],"exampleFix":"// before: keyed access to a plain iterable side input\nside := beam.SideInput{Input: unkeyedPCol}\n// after: materialize as a keyed view first\nkeyed := beam.ParDo(s, func(k string, v string, _ func(*string, func(string) bool)) (string, string) { return k, v }, pcol)\nside := beam.SideInput{Input: keyed} // now keyed/multimap access is valid","handlingStrategy":"validation","validationCode":"if adapter.Kc() == nil { return errors.New(\"side input is unkeyed; use NewIterable not NewKeyedIterable\") }","typeGuard":"func isKeyedSideInput(s *exec.SideInputAdapter) bool { return s != nil && s.HasKeyCoder() }","tryCatchPattern":"stream, err := adapter.NewKeyedIterable(ctx, reader, w, key)\nif err != nil && strings.Contains(err.Error(), \"unkeyed side input\") {\n    stream, err = adapter.NewIterable(ctx, reader, w)\n}","preventionTips":["Match view type (iterable vs multimap) to how the side input is declared","Key the producing PCollection if keyed access is required","Check side input IDs in the pipeline proto match consumers"],"tags":["beam-go","side-input","type-mismatch","coding"],"backgroundTag":"incompatible-source-type","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}