apache/beam · error · ValueError

TupleCoder does not have exactly 2 components.

Error message

TupleCoder does not have exactly 2 components.

What it means

TupleCoder represents a key-value pair and key_coder() only makes sense when it has exactly two component coders. If the coder was constructed with any other number of components, accessing key_coder() raises ValueError rather than returning an index that would silently be wrong.

Solutions

  1. Ensure the TupleCoder is constructed from exactly a KV (2-tuple) typehint or two coders
  2. Inspect coder._coders to confirm the component count before accessing key/value coders
  3. If more components are needed, nest TupleCoders (TupleCoder[TupleCoder[A,B],C]) instead of a flat 3-coder TupleCoder

Example fix

// before
TupleCoder([coder_a, coder_b, coder_c]).key_coder()
// after
TupleCoder([coder_ab, coder_c]).key_coder()  # or TupleCoder([coder_a, coder_b])
Defensive patterns

Strategy: validation

Validate before calling

if len(coder._coders) != 2:
    raise ValueError(f'expected KV coder, got {len(coder._coders)} components')
kc = coder.key_coder()

Type guard

def is_pair_coder(coder) -> bool:
    from apache_beam.coders import TupleCoder
    return isinstance(coder, TupleCoder) and len(coder._coders) == 2

Try / catch

try:
    kc = coder.key_coder()
except ValueError as e:
    log.error('coder is not a KV pair coder: %s', coder)
    raise

Prevention

When it happens

Trigger: Calling key_coder() on a TupleCoder whose _coders list length != 2, e.g. a TupleCoder built from a 3-element tuple typehint or via deserialization of a malformed coder payload.

Common situations: Custom coder plumbing/hand-written CoGroupByKey coders; decoding a coder from the runner/harness that was serialized with a different component count; constructing TupleCoder manually with wrong arity.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

    # type: (typehints.TupleConstraint, CoderRegistry) -> TupleCoder
    return cls([registry.get_coder(t) for t in typehint.tuple_types])

  def _get_component_coders(self):
    # type: () -> Tuple[Coder, ...]
    return self.coders()

  def coders(self):
    # type: () -> Tuple[Coder, ...]
    return self._coders

  def is_kv_coder(self):
    # type: () -> bool
    return len(self._coders) == 2

  def key_coder(self):
    # type: () -> Coder
    if len(self._coders) != 2:
      raise ValueError('TupleCoder does not have exactly 2 components.')
    return self._coders[0]

  def value_coder(self):
    # type: () -> Coder
    if len(self._coders) != 2:
      raise ValueError('TupleCoder does not have exactly 2 components.')
    return self._coders[1]

  def __repr__(self):
    return 'TupleCoder[%s]' % ', '.join(str(c) for c in self._coders)

  def __eq__(self, other):
    return type(self) == type(other) and self._coders == other.coders()

  def __hash__(self):
    return hash(self._coders)

  def to_runner_api_parameter(self, context):

View on GitHub (pinned to 12126d8942)