apache/beam · error · TypeError

coder is not of type Coder

Error message

coder is not of type Coder

What it means

StateSpec.__init__ validates that the coder argument is an instance of apache_beam.coders.Coder. The coder is used to serialize the state cell's values, so arbitrary objects (including None or callables) are rejected with a TypeError.

Solutions

  1. Instantiate the coder: use coders.VarIntCoder() not coders.VarIntCoder
  2. Pass an actual Coder instance as the second argument (or use spec classes with default coders where available)
  3. If using CombiningValueStateSpec, note the coder should describe the accumulator type of the CombineFn (often it can be omitted)

Example fix

// before
spec = StateSpec('count', VarIntCoder)
// after
spec = StateSpec('count', VarIntCoder())
Defensive patterns

Strategy: type-guard

Validate before calling

from apache_beam.coders import Coder
if not isinstance(coder, Coder):
    raise TypeError('coder must be an instantiated Coder')

Type guard

from apache_beam.coders import Coder
def is_coder(c) -> bool:
    return isinstance(c, Coder)

Try / catch

try:
    spec = StateSpec(name, coder)
except TypeError:
    spec = StateSpec(name, DefaultCoder())  # fallback to a known-good coder

Prevention

When it happens

Trigger: Calling StateSpec('name', None), passing a raw class instead of an instance (e.g. VarIntCoder instead of VarIntCoder()), or passing some other non-Coder object as the second argument.

Common situations: Forgetting the () when constructing a coder (VarIntCoder vs VarIntCoder()); passing None because the coder is 'obvious'; mixing up the coder with a type hint or a CombineFn.

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


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

Appendix: source

Thrown at sdks/python/apache_beam/transforms/userstate.py:54

from apache_beam.portability.api import beam_runner_api_pb2
from apache_beam.transforms.timeutil import TimeDomain
from apache_beam.utils import windowed_value
from apache_beam.utils.timestamp import Timestamp

if TYPE_CHECKING:
  from apache_beam.runners.pipeline_context import PipelineContext
  from apache_beam.transforms.core import DoFn

CallableT = TypeVar('CallableT', bound=Callable)


class StateSpec(object):
  """Specification for a user DoFn state cell."""
  def __init__(self, name: str, coder: Coder) -> None:
    if not isinstance(name, str):
      raise TypeError("name is not a string")
    if not isinstance(coder, Coder):
      raise TypeError("coder is not of type Coder")
    self.name = name
    self.coder = coder

  def __repr__(self) -> str:
    return '%s(%s)' % (self.__class__.__name__, self.name)

  def to_runner_api(
      self, context: 'PipelineContext') -> beam_runner_api_pb2.StateSpec:
    raise NotImplementedError


class ReadModifyWriteStateSpec(StateSpec):
  """Specification for a user DoFn value state cell.
     Read more about ReadModifyWriteState (ValueState) here:
     https://beam.apache.org/documentation/programming-guide/#valuestate
  """
  def to_runner_api(
      self, context: 'PipelineContext') -> beam_runner_api_pb2.StateSpec:

View on GitHub (pinned to 12126d8942)