{"record":{"id":"ad02801202f46dfc","repo":"apache/beam","slug":"processelement-doesn-t-use-a-stateprovider-but-state-structs","errorCode":null,"errorMessage":"ProcessElement doesn't use a StateProvider, but State structs are attached to the DoFn: %v\nEnsure that you are using the StateProvider to perform any reads or writesof pipeline state.","messagePattern":"ProcessElement doesn't use a StateProvider, but State structs are attached to the DoFn: (.+?)\nEnsure that you are using the StateProvider to perform any reads or writesof pipeline state\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":1380,"sourceCode":"\t\tstateKeys := make(map[string]state.PipelineState)\n\t\tfor _, s := range ps {\n\t\t\tk := s.StateKey()\n\t\t\tif orig, ok := stateKeys[k]; ok {\n\t\t\t\terr := errors.Errorf(\"Duplicate state key %v\", k)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"Duplicate state key %v used by %v and %v. Ensure that state keys are\"+\n\t\t\t\t\t\"unique per DoFn\", k, orig, s)\n\t\t\t}\n\t\t\tt := s.StateType()\n\t\t\tif t != state.TypeValue && t != state.TypeBag && t != state.TypeCombining && t != state.TypeSet && t != state.TypeMap && t != state.TypeOrderedList {\n\t\t\t\terr := errors.Errorf(\"Unrecognized state type %v for state %v\", t, s)\n\t\t\t\treturn errors.SetTopLevelMsgf(err, \"Unrecognized state type %v for state %v. Currently the only supported state\"+\n\t\t\t\t\t\"types are state.Value, state.Combining, state.Bag, state.Set, state.Map, and state.OrderedList\", t, s)\n\t\t\t}\n\t\t\tstateKeys[k] = s\n\t\t}\n\t} else {\n\t\tif len(ps) > 0 {\n\t\t\terr := errors.Errorf(\"ProcessElement doesn't use a StateProvider, but State structs are attached to \"+\n\t\t\t\t\"the DoFn: %v\", ps)\n\t\t\treturn errors.SetTopLevelMsgf(err, \"ProcessElement doesn't use a StateProvider, but State structs are \"+\n\t\t\t\t\"attached to the DoFn: %v\\nEnsure that you are using the StateProvider to perform any reads or writes\"+\n\t\t\t\t\"of pipeline state.\", ps)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc validateOnTimerFn(fn *DoFn) error {\n\tif _, ok := fn.methods[onTimerName]; !ok {\n\t\terr := errors.Errorf(\"OnTimer function not defined for DoFn: %v\", fn.Name())\n\t\treturn errors.SetTopLevelMsgf(err, \"OnTimer function not defined for DoFn: %v. Ensure that OnTimer function is implemented for the DoFn.\", fn.Name())\n\t}\n\n\tpipelineTimers, _ := fn.PipelineTimers()\n","sourceCodeStart":1362,"sourceCodeEnd":1398,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L1362-L1398","documentation":"The inverse of the stateful misconfiguration: this error is thrown when a DoFn has State structs attached but ProcessElement does not declare a StateProvider parameter. Attached State fields are inert unless the method takes a state.Provider to read/write them, so Beam flags the DoFn as incorrectly configured.","triggerScenarios":"Declaring State fields on a DoFn (state.Value, state.Bag, etc.) while ProcessElement's signature lacks the state.Provider parameter, e.g. after removing the provider argument during a refactor while leaving the fields behind.","commonSituations":"Stripping state usage from a DoFn but forgetting to remove the fields; copying a stateful DoFn and removing the provider parameter; scaffolding state fields before wiring up the method.","solutions":["Add a state.Provider parameter to ProcessElement (and key the input as KV) and use it to read/write the State fields.","Remove the unused State fields from the DoFn struct if state is no longer needed.","Verify ProcessElement's signature includes state.Provider before any State fields are declared."],"exampleFix":"// before\ntype CountFn struct {\n    Seen state.Value[string, int]\n}\nfunc (fn *CountFn) ProcessElement(ctx context.Context, w beam.KV[string, int]) error { ... }\n// after\nfunc (fn *CountFn) ProcessElement(ctx context.Context, sp state.Provider, w beam.KV[string, int]) error {\n    _, ok, err := fn.Seen.Read(sp)\n    ...\n}","handlingStrategy":"validation","validationCode":"hasStateFields := numExportedStateFields(fn) > 0\nhasProvider := signatureHasStateProvider(fn.ProcessElement)\nif hasStateFields && !hasProvider {\n    log.Fatal(\"DoFn declares State fields but ProcessElement takes no state.Provider\")\n}","typeGuard":null,"tryCatchPattern":"if err := beam.Run(ctx, p); err != nil {\n    if strings.Contains(err.Error(), \"doesn't use a StateProvider, but State structs are attached\") {\n        log.Fatalf(\"wire state.Provider into ProcessElement or delete unused State fields: %v\", err)\n    }\n    return err\n}","preventionTips":["Treat State fields and the state.Provider parameter as a pair — add or remove them together","Delete leftover State fields when removing stateful logic","Add a compile-time test that builds the DoFn and runs graph validation"],"tags":["go","apache-beam","dofn","state","signature-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}