{"record":{"id":"5f03c29c54a8435f","repo":"apache/beam","slug":"cannot-make-a-state-provider-for-an-unkeyed-input-v","errorCode":null,"errorMessage":"cannot make a state provider for an unkeyed input %v","messagePattern":"cannot make a state provider for an unkeyed input (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/exec/userstate.go","lineNumber":662,"sourceCode":"// NewUserStateAdapter returns a user state adapter for the given StreamID and coder.\n// It expects a W<V> or W<KV<K,V>> coder, because the protocol requires windowing information.\nfunc NewUserStateAdapter(sid StreamID, c *coder.Coder, stateIDToCoder map[string]*coder.Coder, stateIDToKeyCoder map[string]*coder.Coder, stateIDToCombineFn map[string]*graph.CombineFn) UserStateAdapter {\n\tif !coder.IsW(c) {\n\t\tpanic(fmt.Sprintf(\"expected WV coder for user state %v: %v\", sid, c))\n\t}\n\n\twc := MakeWindowEncoder(c.Window)\n\tvar kc ElementEncoder\n\tif coder.IsKV(coder.SkipW(c)) {\n\t\tkc = MakeElementEncoder(coder.SkipW(c).Components[0])\n\t}\n\treturn &userStateAdapter{sid: sid, wc: wc, kc: kc, c: c, stateIDToCoder: stateIDToCoder, stateIDToKeyCoder: stateIDToKeyCoder, stateIDToCombineFn: stateIDToCombineFn}\n}\n\n// NewStateProvider creates a stateProvider with the ability to talk to the state API.\nfunc (s *userStateAdapter) NewStateProvider(ctx context.Context, reader StateReader, w typex.Window, element any) (stateProvider, error) {\n\tif s.kc == nil {\n\t\treturn stateProvider{}, fmt.Errorf(\"cannot make a state provider for an unkeyed input %v\", element)\n\t}\n\telementKey, err := EncodeElement(s.kc, element.(*MainInput).Key.Elm)\n\tif err != nil {\n\t\treturn stateProvider{}, err\n\t}\n\n\twin, err := EncodeWindow(s.wc, w)\n\tif err != nil {\n\t\treturn stateProvider{}, err\n\t}\n\tsp := stateProvider{\n\t\tctx:                      ctx,\n\t\tsr:                       reader,\n\t\tSID:                      s.sid,\n\t\telementKey:               elementKey,\n\t\twindow:                   win,\n\t\ttransactionsByKey:        make(map[string][]state.Transaction),\n\t\tinitialValueByKey:        make(map[string]any),","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/exec/userstate.go#L644-L680","documentation":"userStateAdapter.NewStateProvider creates a state provider bound to a keyed element. Keyed state requires a key coder (kc); when the input was registered without a key (unkeyed), no state can be scoped to an element key, so the call fails naming the element. It mirrors the keyed side-input check: state APIs are only valid for keyed PCollections.","triggerScenarios":"Calling NewStateProvider on a userStateAdapter built with kc == nil — i.e. using stateful DoFn state APIs (bag, map, ordered list, combining state) against a main input that has no key.","commonSituations":"Adding state annotations (SetupProcessBundle state specs) to a DoFn whose main input is not a KV; building a pipeline in Go where the input PCollection was never keyed (missing ParDo/KV step); custom runners wiring state adapters for unkeyed inputs.","solutions":["Key the input PCollection before the stateful transform (emit KVs, e.g. via beam.ParDo mapping element -> KV(key, element)).","Remove state usage from the DoFn if per-key state is not actually needed.","Check the state spec's key coder is populated in the pipeline proto (stateIDToKeyCoder).","Verify the DoFn's main input type is a KV matching the declared key coder."],"exampleFix":"// before: stateful DoFn over unkeyed elements\nbeam.ParDo(s, statefulFn, unkeyedPCol)\n// after: key elements first\nkeyed := beam.ParDo(s, func(v string) (string, string) { return keyFor(v), v }, unkeyedPCol)\nbeam.ParDo(s, statefulFn, keyed)","handlingStrategy":"validation","validationCode":"if adapter.Kc() == nil { return errors.New(\"state requires a keyed input; key the PCollection first\") }","typeGuard":"func supportsState(a *exec.UserStateAdapter) bool { return a != nil && a.HasKeyCoder() }","tryCatchPattern":"sp, err := adapter.NewStateProvider(ctx, reader, w, element)\nif err != nil && strings.Contains(err.Error(), \"unkeyed input\") {\n    return nil, fmt.Errorf(\"stateful DoFn used over unkeyed input: %w\", err)\n}","preventionTips":["Only attach state APIs to DoFns whose main input is a KV","Key the PCollection before the stateful transform","Verify key coders are populated in the bundle's state specs"],"tags":["beam-go","state-api","keyed-state","type-mismatch"],"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"}