{"record":{"id":"2ff280c3433d693a","repo":"apache/beam","slug":"tuple-type-constraint-violated-valid-object-instance-must-be","errorCode":null,"errorMessage":"Tuple type constraint violated. Valid object instance must be of type 'tuple'. Instead, an instance of '%s' was received.","messagePattern":"Tuple type constraint violated\\. Valid object instance must be of type 'tuple'\\. Instead, an instance of '(.+?)' was received\\.","errorType":"validation","errorClass":"CompositeTypeHintError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/typehints/typehints.py","lineNumber":718,"sourceCode":"\n    def _inner_types(self):\n      for t in self.tuple_types:\n        yield t\n\n    def _constraint_for_index(self, idx):\n      \"\"\"Returns the type at the given index.\"\"\"\n      return self.tuple_types[idx]\n\n    def _consistent_with_check_(self, sub):\n      return (\n          isinstance(sub, self.__class__) and\n          len(sub.tuple_types) == len(self.tuple_types) and all(\n              is_consistent_with(sub_elem, elem)\n              for sub_elem, elem in zip(sub.tuple_types, self.tuple_types)))\n\n    def type_check(self, tuple_instance):\n      if not isinstance(tuple_instance, tuple):\n        raise CompositeTypeHintError(\n            \"Tuple type constraint violated. Valid object instance must be of \"\n            \"type 'tuple'. Instead, an instance of '%s' was received.\" %\n            tuple_instance.__class__.__name__)\n\n      if len(tuple_instance) != len(self.tuple_types):\n        raise CompositeTypeHintError(\n            'Passed object instance is of the proper type, but differs in '\n            'length from the hinted type. Expected a tuple of length %s, '\n            'received a tuple of length %s.' %\n            (len(self.tuple_types), len(tuple_instance)))\n\n      for type_pos, (expected, actual) in enumerate(zip(self.tuple_types,\n                                                        tuple_instance)):\n        try:\n          check_constraint(expected, actual)\n          continue\n        except SimpleTypeHintError:\n          raise CompositeTypeHintError(","sourceCodeStart":700,"sourceCodeEnd":736,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/typehints/typehints.py#L700-L736","documentation":"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.","triggerScenarios":"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].","commonSituations":"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.","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."],"exampleFix":"# before\nbeam.Map(lambda row: row.split(','))  # list, hinted Tuple[str, int]\n# after\nbeam.Map(lambda row: (row.split(',')[0], int(row.split(',')[1])))","handlingStrategy":"type-guard","validationCode":"def as_tuple(value, n):\n    v = tuple(value)\n    assert isinstance(v, tuple) and len(v) == n, f'expected {n}-tuple, got {v!r}'\n    return v","typeGuard":"def is_tuple_of(value, *types_):\n    return isinstance(value, tuple) and len(value) == len(types_) and all(isinstance(x, t) for x, t in zip(value, types_))","tryCatchPattern":"try:\n    expand(pcoll)\nexcept CompositeTypeHintError as e:\n    if \"must be of type 'tuple'\" in str(e):\n        logger.error('non-tuple where Tuple hint expected: %s', e)\n    raise","preventionTips":["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"],"tags":["python","apache-beam","typehints","tuple"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}