apache/beam · error · CompositeTypeHintError
Tuple type constraint violated. Valid object instance must…
Error message
Tuple type constraint violated. Valid object instance must be of type 'tuple'. Instead, an instance of '%s' was received.
What it means
TupleHint's inner type_check raises CompositeTypeHintError when an object checked against a Tuple[...] hint is not a Python tuple at all. Beam requires the instance's class to be exactly tuple before comparing arity and per-position element types.
Solutions
- Convert the value to a tuple at production time: tuple(value) in the emitting Map/DoFn.
- Change the hint to List[...] if the data is genuinely a variable-length list.
- Ensure arity matches too — the next check enforces len == number of hinted types.
- For key/value data, produce explicit tuples like (k, v) instead of lists.
Example fix
# before
beam.Map(lambda row: row.split(',')) # list, hinted Tuple[str, int]
# after
beam.Map(lambda row: (row.split(',')[0], int(row.split(',')[1]))) Defensive patterns
Strategy: type-guard
Validate before calling
def as_tuple(value, n):
v = tuple(value)
assert isinstance(v, tuple) and len(v) == n, f'expected {n}-tuple, got {v!r}'
return v Type guard
def is_tuple_of(value, *types_):
return isinstance(value, tuple) and len(value) == len(types_) and all(isinstance(x, t) for x, t in zip(value, types_)) Try / catch
try:
expand(pcoll)
except CompositeTypeHintError as e:
if "must be of type 'tuple'" in str(e):
logger.error('non-tuple where Tuple hint expected: %s', e)
raise Prevention
- Produce literal tuples in Map/DoFn when hints are Tuple[...]
- Convert JSON/CSV-derived lists to tuples before typed stages
- Check arity matches the number of hinted element types
When it happens
Trigger: Passing a list, namedtuple-like list, or generator where a Tuple[T1, T2, ...] hint expects a tuple, e.g. a transform with_output_types(Tuple[str, int]) emitting ['a', 1].
Common situations: JSON deserialization yields lists instead of tuples; Map functions returning lists for KV-style data hinted as Tuple; converting code from List hints to Tuple hints without changing producers.
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
- An Option type-hint only accepts a single type parameter.
- bad type
- batch type must be List[T] for element type T
- batch type must be np.ndarray or…
- Cannot create Union without a sequence of types.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/2ff280c3433d693a.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/typehints/typehints.py:718
def _inner_types(self):
for t in self.tuple_types:
yield t
def _constraint_for_index(self, idx):
"""Returns the type at the given index."""
return self.tuple_types[idx]
def _consistent_with_check_(self, sub):
return (
isinstance(sub, self.__class__) and
len(sub.tuple_types) == len(self.tuple_types) and all(
is_consistent_with(sub_elem, elem)
for sub_elem, elem in zip(sub.tuple_types, self.tuple_types)))
def type_check(self, tuple_instance):
if not isinstance(tuple_instance, tuple):
raise CompositeTypeHintError(
"Tuple type constraint violated. Valid object instance must be of "
"type 'tuple'. Instead, an instance of '%s' was received." %
tuple_instance.__class__.__name__)
if len(tuple_instance) != len(self.tuple_types):
raise CompositeTypeHintError(
'Passed object instance is of the proper type, but differs in '
'length from the hinted type. Expected a tuple of length %s, '
'received a tuple of length %s.' %
(len(self.tuple_types), len(tuple_instance)))
for type_pos, (expected, actual) in enumerate(zip(self.tuple_types,
tuple_instance)):
try:
check_constraint(expected, actual)
continue
except SimpleTypeHintError:
raise CompositeTypeHintError(View on GitHub (pinned to 12126d8942)