apache/beam · error · TypeError
Unable to deterministically encode '%s' of type '%s', please
Error message
Unable to deterministically encode '%s' of type '%s', please provide a type hint for the input of '%s'
What it means
In encode_special_deterministic, when a value is not a proto/frozen-dataclass/namedtuple/enum/stateful object, the coder falls back to raising TypeError via _deterministic_encoding_error_msg. Without a known structured type, Beam cannot guarantee reproducible bytes for objects like arbitrary class instances (it would otherwise pickle them, which is not deterministic). The message asks for a type hint so Beam can pick a deterministic coder.
Source
Thrown at sdks/python/apache_beam/coders/coder_impl.py:518
"Unable to deterministically encode non-frozen '%s' of type '%s' "
"for the input of '%s'" %
(value, type(value), self.requires_deterministic_step_label))
init_fields = [field for field in dataclasses.fields(value) if field.init]
try:
if any(field.kw_only for field in init_fields):
stream.write_byte(DATACLASS_KW_ONLY_TYPE)
self.encode_type(type(value), stream)
stream.write_var_int64(len(init_fields))
for field in init_fields:
stream.write(field.name.encode("utf-8"), True)
self.encode_to_stream(getattr(value, field.name), stream, True)
else: # Not using kw_only, we can pass parameters by position.
stream.write_byte(DATACLASS_TYPE)
self.encode_type(type(value), stream)
values = [getattr(value, field.name) for field in init_fields]
self.iterable_coder_impl.encode_to_stream(values, stream, True)
except Exception as e:
raise TypeError(self._deterministic_encoding_error_msg(value)) from e
elif isinstance(value, tuple) and hasattr(type(value), '_fields'):
stream.write_byte(NAMED_TUPLE_TYPE)
self.encode_type(type(value), stream)
try:
self.iterable_coder_impl.encode_to_stream(value, stream, True)
except Exception as e:
raise TypeError(self._deterministic_encoding_error_msg(value)) from e
elif isinstance(value, enum.Enum):
stream.write_byte(ENUM_TYPE)
self.encode_type(type(value), stream)
# Enum values can be of any type.
try:
self.encode_to_stream(value.value, stream, True)
except Exception as e:
raise TypeError(self._deterministic_encoding_error_msg(value)) from e
elif (hasattr(value, "__getstate__") and
# https://github.com/apache/beam/issues/33020
type(value).__reduce__ == object.__reduce__):View on GitHub (pinned to 12126d8942)
Solutions
- Provide a type hint (e.g. input/output type on the DoFn or PTransform) matching a deterministically encodable type (str, bytes, int, Tuple, NamedTuple, frozen dataclass).
- Replace dict/set values with sorted tuples or NamedTuples before using them as keys.
- Define __getstate__/__setstate__ (and keep default __reduce__) on the class so the nested-state deterministic path is used.
- Wrap the value into a frozen dataclass or NamedTuple key.
Example fix
// before
class ExtractKey(beam.DoFn):
def process(self, element):
yield (element['meta'], element['value']) # dict key
// after
class MetaKey(typing.NamedTuple):
a: str
b: int
class ExtractKey(beam.DoFn):
def process(self, element) -> Tuple[MetaKey, int]:
yield (MetaKey(element['a'], element['b']), element['value']) Defensive patterns
Strategy: validation
Validate before calling
def is_deterministically_encodable(value):
import dataclasses, enum
if isinstance(value, (str, bytes, int, float, bool)):
return True
if dataclasses.is_dataclass(value) and type(value).__dataclass_params__.frozen:
return True
if isinstance(value, tuple) and hasattr(type(value), '_fields'):
return all(is_deterministically_encodable(v) for v in value)
if isinstance(value, enum.Enum):
return is_deterministically_encodable(value.value)
return False Type guard
def is_encodable_key(value) -> bool:
return isinstance(value, (str, bytes, int, float, bool)) or (isinstance(value, tuple) and hasattr(type(value), '_fields')) Try / catch
try:
coder.encode(key)
except TypeError as e:
raise ValueError(f"Key {key!r} is not deterministically encodable; use a NamedTuple/frozen dataclass") from e Prevention
- Add explicit type hints to every DoFn output used as a key
- Never use dict or set as a GroupByKey key
- Test encode round-trips in unit tests before running pipelines
When it happens
Trigger: Encoding an arbitrary class instance (or set/dict or other unstructured value) as the input to a determinism-requiring step (e.g. GroupByKey keys) with no type hint registered; the final else branch in encode_special_deterministic raises via self._deterministic_encoding_error_msg(value).
Common situations: Passing custom objects or sets as GroupByKey/CoGroupByKey keys; omitting type hints on DoFn outputs so Beam falls back to Any/pickle; dict/set used as a key which has no deterministic iteration order.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Unable to deterministically encode non-frozen '%s' of type '
- Unable to deterministically encode '%s' of type '%s', for th
- Unknown PaneInfo encoding 0x" + encoding.toString(16)
- cannot encode a null Integer
- cannot encode a null Long
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0d56da60453db4eb.
Report an issue: GitHub.