{"record":{"id":"737b891851b4ad1f","repo":"apache/beam","slug":"input-to-flatten-must-be-an-iterable-got-a-value-of-type-s","errorCode":null,"errorMessage":"Input to Flatten must be an iterable. Got a value of type %s instead.","messagePattern":"Input to Flatten must be an iterable\\. Got a value of type (.+?) instead\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/core.py","lineNumber":4110,"sourceCode":"  Args:\n    **kwargs: Accepts a single named argument \"pipeline\", which specifies the\n      pipeline that \"owns\" this PTransform. Ordinarily Flatten can obtain this\n      information from one of the input PCollections, but if there are none (or\n      if there's a chance there may be none), this argument is the only way to\n      provide pipeline information and should be considered mandatory.\n  \"\"\"\n  def __init__(self, **kwargs):\n    super().__init__()\n    self.pipeline = kwargs.pop(\n        'pipeline', None)  # type: typing.Optional[Pipeline]\n    if kwargs:\n      raise ValueError('Unexpected keyword arguments: %s' % list(kwargs))\n\n  def _extract_input_pvalues(self, pvalueish):\n    try:\n      pvalueish = tuple(pvalueish)\n    except TypeError:\n      raise ValueError(\n          'Input to Flatten must be an iterable. '\n          'Got a value of type %s instead.' % type(pvalueish))\n\n    # Spot check to see if any of the items are iterables of PCollections\n    # and raise an error if so. This is always a user-error\n    for idx, item in enumerate(pvalueish):\n      if isinstance(item, (list, tuple)) and any(\n          isinstance(sub_item, pvalue.PCollection) for sub_item in item):\n        raise TypeError(\n            'Inputs to Flatten cannot include an iterable of PCollections. '\n            f'(input at index {idx}: \"{item}\")')\n    return pvalueish, pvalueish\n\n  def expand(self, pcolls):\n    windowing = self.get_windowing(pcolls)\n    for pcoll in pcolls:\n      self._check_pcollection(pcoll)\n      if pcoll.windowing != windowing:","sourceCodeStart":4092,"sourceCodeEnd":4128,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/core.py#L4092-L4128","documentation":"Raised by Flatten._extract_input_pvalues when the input cannot be converted to a tuple, i.e. it is not an iterable of PCollections. Flatten needs a collection of input PCollections to merge; a single bare PCollection or a non-iterable value cannot be flattened.","triggerScenarios":"pc | beam.Flatten() where pc is a single PCollection rather than a tuple/list of them; passing a dict or scalar; calling Flatten on a generator that has been exhausted (raising TypeError on tuple()).","commonSituations":"Mistakenly piping one PCollection directly to Flatten instead of a tuple; building the input list conditionally and ending up with None; passing a dict where a list was intended.","solutions":["Pass a tuple/list of PCollections: result = (pc1, pc2, pc3) | beam.Flatten().","If inputs are in a list variable: result = pcoll_list | beam.Flatten().","To pass a single collection through unchanged, skip Flatten or wrap it: (single_pcoll,) | beam.Flatten().","Verify the value is not None/exhausted before piping."],"exampleFix":"// before\nmerged = pc | beam.Flatten()  # pc is a single PCollection\n// after\nmerged = [pc1, pc2, pc3] | beam.Flatten()","handlingStrategy":"type-guard","validationCode":"assert isinstance(inputs, (list, tuple)) and all(isinstance(x, PCollection) for x in inputs), 'Flatten needs an iterable of PCollections'","typeGuard":"def is_pcollection_iterable(v):\n    try:\n        items = list(v)\n    except TypeError:\n        return False\n    return all(isinstance(x, PCollection) for x in items)","tryCatchPattern":"try:\n    merged = inputs | beam.Flatten()\nexcept ValueError as e:\n    log.error('Flatten input not iterable of PCollections: %s', e)","preventionTips":["Pass tuples/lists of PCollections, never a single PCollection","Check for None or exhausted generators before piping","Wrap single collections as (pcoll,)"],"tags":["python","apache-beam","flatten","iterable"],"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"}