apache/beam · error

State type %v not recognized for state %v

Error message

State type %v not recognized for state %v

What it means

While emitting pipepb.StateSpec entries for a stateful DoFn, addMultiEdge hit a state.ProviderSpec whose StateType is not one of the recognized types (Value, Bag/Map/Set, Combining, OrderedList). The translator throws to avoid generating an invalid StateSpec for the state named in the message.

Source

Thrown at sdks/go/pkg/beam/core/runtime/graphx/translate.go:617

							},
						},
						Protocol: &pipepb.FunctionSpec{
							Urn: URNMultiMapUserState,
						},
					}
				case state.TypeOrderedList:
					stateSpecs[ps.StateKey()] = &pipepb.StateSpec{
						Spec: &pipepb.StateSpec_OrderedListSpec{
							OrderedListSpec: &pipepb.OrderedListStateSpec{
								ElementCoderId: coderID,
							},
						},
						Protocol: &pipepb.FunctionSpec{
							Urn: URNOrderedListUserState,
						},
					}
				default:
					return nil, errors.Errorf("State type %v not recognized for state %v", ps.StateKey(), ps)
				}
			}
			payload.StateSpecs = stateSpecs
		}
		if _, ok := edge.Edge.DoFn.ProcessElementFn().TimerProvider(); ok {
			m.requirements[URNRequiresStatefulProcessing] = true
			timerSpecs := make(map[string]*pipepb.TimerFamilySpec)
			pipelineTimers, _ := edge.Edge.DoFn.PipelineTimers()

			// All timers for a single DoFn have the same key and window coders, that match the input PCollection.
			mainInputID := inputs["i0"]
			pCol := m.pcollections[mainInputID]
			kvCoder := m.coders.coders[pCol.CoderId]
			if kvCoder.GetSpec().GetUrn() != urnKVCoder {
				return nil, errors.Errorf("timer using DoFn %v doesn't use a KV as PCollection input. Unable to extract key coder for timers, got %v", edge.Name, kvCoder.GetSpec().GetUrn())
			}
			keyCoderID := kvCoder.GetComponentCoderIds()[0]

View on GitHub (pinned to 12126d8942)

Solutions

  1. Check ps.StateType() against the supported set (Value, Bag, Multimap, Combining, OrderedList)
  2. Upgrade to an SDK version that handles your state type
  3. Switch to a supported state type (e.g. use BagState instead of the unsupported kind)
  4. File a Beam issue if a documented state type is unhandled

Example fix

// before: custom state type not handled
type fn struct { s myCustomState }
// after: use supported state
var _ = state.Value[string, int64](scope, "s")
Defensive patterns

Strategy: validation

Validate before calling

// Reject state types unsupported by the marshaller before building the pipeline
allowed := map[state.Type]bool{state.TypeValue: true, state.TypeBag: true, state.TypeMultimap: true, state.TypeCombining: true, state.TypeOrderedList: true}
if !allowed[ps.StateType()] {
    return fmt.Errorf("state %q uses unsupported type %v", ps.StateKey(), ps.StateType())
}

Type guard

func isSupportedStateType(t state.Type) bool {
    switch t {
    case state.TypeValue, state.TypeBag, state.TypeMultimap, state.TypeCombining, state.TypeOrderedList:
        return true
    }
    return false
}

Try / catch

if _, err := graphx.Marshal(p); err != nil {
    if strings.Contains(err.Error(), "State type") && strings.Contains(err.Error(), "not recognized") {
        return fmt.Errorf("upgrade SDK or change state type: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Marshalling a pipeline whose DoFn uses a custom or newer state type not yet supported by the graphx translator — e.g. a state kind added to the state package but not handled in the switch here.

Common situations: SDK version skew where userstate package gained a new state type before translate.go handled it; custom state implementations in embedded runners or tests.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/3d03e59c4139ad20. Report an issue: GitHub.