apache/beam · error · TypeError

Coder registration requires a coder class object. Received…

Error message

Coder registration requires a coder class object. Received %r instead.

What it means

CoderRegistry.register_coder maps a type hint to a coder class. It requires the coder argument to be an actual class (type), not an instance or other object; anything else raises TypeError. Instances are rejected because coders are instantiated per-pipeline by the registry.

Solutions

  1. Pass the coder class itself, not an instance: register_coder(MyType, MyCoder).
  2. Ensure the coder subclasses Coder and is defined at module level.
  3. For dataclasses/named tuples use register_row instead of register_coder.
  4. Check for name shadowing where MyCoder was reassigned to an instance earlier.

Example fix

// before
registry.register_coder(MyCustomType, MyCustomCoder())
// after
registry.register_coder(MyCustomType, MyCustomCoder)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(coder_cls, type):
    raise TypeError('register_coder expects a class, got instance/other')

Type guard

def is_coder_class(obj) -> bool:
    import inspect
    from apache_beam.coders import Coder
    return isinstance(obj, type) and inspect.isclass(obj) and issubclass(obj, Coder)

Try / catch

try:
    typecoders.registry.register_coder(my_type, coder_cls)
except TypeError as e:
    if 'coder class object' in str(e):
        coder_cls = type(coder_cls)  # unwrap accidental instance
        typecoders.registry.register_coder(my_type, coder_cls)
    else:
        raise

Prevention

When it happens

Trigger: Calling registry.register_coder(MyType, MyCoder()) with an instance instead of the class; passing a functools.partial, lambda, or a mocked object; accidentally shadowing the coder class with a variable holding an instance.

Common situations: Users wiring custom coders in __init__ or pipeline setup; copying example code and instantiating the coder; test fakes substituting a mock for the class.

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/a9d3e0bc74576c4f. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/coders/typecoders.py:138

  def register_coder(
      self, typehint_type: Any,
      typehint_coder_class: type[coders.Coder]) -> None:
    """
    Register a user type with a coder.

    Typical usage::

      class MyCustomType:
        pass

      coders.registry.register_coder(MyCustomType, MyCustomCoder)

    To register a supported user type (data class or named tuple) with Beam Row,
    use :meth:`register_row` instead, as it registers both coder and schema.
    """
    if not isinstance(typehint_coder_class, type):
      raise TypeError(
          'Coder registration requires a coder class object. '
          'Received %r instead.' % typehint_coder_class)
    if typehint_type not in self.custom_types:
      self.custom_types.append(typehint_type)
    self._register_coder_internal(
        self._normalize_typehint_type(typehint_type), typehint_coder_class)

  def register_row(self, typehint_type: type[Any]) -> type[Any]:
    """
    Register a user type with a Beam Row.

    This registers the type with a RowCoder and register its schema.

    Register a dataclass::

      @coders.registry.register_row
      @dataclass
      class MyDataClass:

View on GitHub (pinned to 12126d8942)