apache/beam · error · NotImplementedError

value_coder: %s

Error message

value_coder: %s

What it means

Mirror of key_coder(): Coder.value_coder() raises NotImplementedError when the coder says it is a KV coder but does not implement the value-component access in the base class. The base class provides no value coder, so subclasses must implement it.

Source

Thrown at sdks/python/apache_beam/coders/coders.py:268

    # type: (Type[CoderT], Any, CoderRegistry) -> CoderT
    # If not overridden, just construct the coder without arguments.
    return cls()

  def is_kv_coder(self):
    # type: () -> bool
    return False

  def key_coder(self):
    # type: () -> Coder
    if self.is_kv_coder():
      raise NotImplementedError('key_coder: %s' % self)
    else:
      raise ValueError('Not a KV coder: %s.' % self)

  def value_coder(self):
    # type: () -> Coder
    if self.is_kv_coder():
      raise NotImplementedError('value_coder: %s' % self)
    else:
      raise ValueError('Not a KV coder: %s.' % self)

  def _get_component_coders(self):
    # type: () -> Sequence[Coder]

    """For internal use only; no backwards-compatibility guarantees.

    Returns the internal component coders of this coder."""
    # This is an internal detail of the Coder API and does not need to be
    # refined in user-defined Coders.
    return []

  def __repr__(self):
    return self.__class__.__name__

  # pylint: disable=protected-access
  def __eq__(self, other):

View on GitHub (pinned to 12126d8942)

Solutions

  1. Override value_coder()/key_coder() or _get_component_coders() in the custom coder
  2. Use coders.TupleCoder for KV data
  3. Fix is_kv_coder() to return False if the coder truly has no value component

Example fix

// before
class MyKVCoder(Coder):
    pass  # is_kv_coder() defaults truthy path
// after
class MyKVCoder(Coder):
    def value_coder(self):
        return coders.StrBytesCoder()
Defensive patterns

Strategy: type-guard

Validate before calling

if coder.is_kv_coder() and type(coder).value_coder is Coder.value_coder:
    raise TypeError('coder claims KV but lacks value_coder')

Type guard

def has_value_coder(coder):
    return coder.is_kv_coder() and type(coder).value_coder is not Coder.value_coder

Try / catch

try:
    vc = coder.value_coder()
except NotImplementedError as e:
    log.error('no value coder for %s: %s', coder, e)
    vc = default_value_coder

Prevention

When it happens

Trigger: Calling value_coder() on a custom coder whose is_kv_coder() returns True without an overridden value_coder/_get_component_coders; framework probes during grouping or runner planning.

Common situations: Custom KV coders missing the component coder API; base Coder used where TupleCoder was intended.

Related errors


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