apache/beam · error · NotImplementedError
ToBytesCoder cannot be used for decoding.
Error message
ToBytesCoder cannot be used for decoding.
What it means
ToBytesCoder is a write-only convenience coder: its encode converts anything to bytes, but it intentionally does not implement decode and raises NotImplementedError('ToBytesCoder cannot be used for decoding.') whenever decoding is attempted. It exists as a default when no sink coder is specified and reading back is never expected.
Source
Thrown at sdks/python/apache_beam/coders/coders.py:435
def is_deterministic(self):
# type: () -> bool
return True
def to_type_hint(self):
return str
Coder.register_structured_urn(common_urns.coders.STRING_UTF8.urn, StrUtf8Coder)
class ToBytesCoder(Coder):
"""A default string coder used if no sink coder is specified."""
def encode(self, value):
return value if isinstance(value, bytes) else str(value).encode('utf-8')
def decode(self, _):
raise NotImplementedError('ToBytesCoder cannot be used for decoding.')
def is_deterministic(self):
# type: () -> bool
return True
# alias to the old class name for a courtesy to users who reference it
ToStringCoder = ToBytesCoder
class FastCoder(Coder):
"""Coder subclass used when a (faster) CoderImpl is supplied directly.
The Coder class defines _create_impl in terms of encode() and decode();
this class inverts that by defining encode() and decode() in terms of
_create_impl().
"""
def encode(self, value):View on GitHub (pinned to 12126d8942)
Solutions
- Replace ToBytesCoder with a decodable coder such as coders.StrBytesCoder (or coders.BytesCoder for raw bytes)
- Keep ToBytesCoder only on write-only paths where values are never read back
- Decode at write time instead: store str/bytes elements and use a coder that round-trips
Example fix
// before pcoll = pcoll | beam.Map(lambda x: str(x)) with coder ToBytesCoder() ... later decoded // after pcoll = pcoll | beam.Map(lambda x: str(x)) with coder coders.StrBytesCoder()
Defensive patterns
Strategy: try-catch
Validate before calling
if isinstance(coder, ToBytesCoder) and need_decoding:
coder = coders.StrBytesCoder() Type guard
def is_decodable_coder(coder):
return not isinstance(coder, ToBytesCoder) and coder.is_deterministic() is not None Try / catch
try:
value = coder.decode(blob)
except NotImplementedError:
value = blob.decode('utf-8') # ToBytesCoder wrote str(x).encode('utf-8') Prevention
- Never use ToBytesCoder where data will be read back
- Use StrBytesCoder/BytesCoder for string/bytes data
- Check coder round-trip support when choosing sink coders
When it happens
Trigger: Calling ToBytesCoder().decode(bytes) directly; pipelines or checkpoint mechanisms that try to read back data written with ToBytesCoder (checkpoint marks, side-input materialization, bag page values).
Common situations: Using ToBytesCoder as a general-purpose string coder because the name suggests 'to bytes', then a transform needs to decode; writing to sinks with the default coder and later reading that data in another step/job.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Decode not implemented: %s.
- key_coder: %s
- Not a KV coder: %s.
- value_coder: %s
- Typehint is not of nullable type, and cannot be converted to
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/797d1e2c76c388cb.
Report an issue: GitHub.