{"record":{"id":"7613189b2b301005","repo":"apache/beam","slug":"expecting-a-pcollection-argument","errorCode":null,"errorMessage":"Expecting a PCollection argument.","messagePattern":"Expecting a PCollection argument\\.","errorType":"exception","errorClass":"TransformError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/ptransform.py","lineNumber":569,"sourceCode":"  def __str__(self):\n    return '<%s>' % self._str_internal()\n\n  def __repr__(self):\n    return '<%s at %s>' % (self._str_internal(), hex(id(self)))\n\n  def _str_internal(self):\n    return '%s(PTransform)%s%s%s' % (\n        self.__class__.__name__,\n        ' label=[%s]' % self.label if\n        (hasattr(self, 'label') and self.label) else '',\n        ' inputs=%s' % str(self.inputs) if\n        (hasattr(self, 'inputs') and self.inputs) else '',\n        ' side_inputs=%s' % str(self.side_inputs) if self.side_inputs else '')\n\n  def _check_pcollection(self, pcoll):\n    # type: (pvalue.PCollection) -> None\n    if not isinstance(pcoll, pvalue.PCollection):\n      raise error.TransformError('Expecting a PCollection argument.')\n    if not pcoll.pipeline:\n      raise error.TransformError('PCollection not part of a pipeline.')\n\n  def get_windowing(self, inputs):\n    # type: (Any) -> Windowing\n\n    \"\"\"Returns the window function to be associated with transform's output.\n\n    By default most transforms just return the windowing function associated\n    with the input PCollection (or the first input if several).\n    \"\"\"\n    if inputs:\n      return inputs[0].windowing\n    else:\n      from apache_beam.transforms.core import Windowing\n      from apache_beam.transforms.window import GlobalWindows\n\n      # TODO(robertwb): Return something compatible with every windowing?","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/ptransform.py#L551-L587","documentation":"PTransform._check_pcollection validates that an argument passed to expand() is actually a PCollection instance. Raising TransformError here means a non-PCollection (list, dict, PBegin, DeferredExpression, etc.) was passed where a PCollection is required.","triggerScenarios":"Calling an expand() that checks its inputs with something like a plain Python list, a dict, a string, or a materialized value instead of a PCollection produced by a prior transform.","commonSituations":"Feeding raw lists into custom transforms instead of beam.Create(...); reusing a variable that was reassigned to non-PCollection data; mistakenly passing a side input value as the main input.","solutions":["Wrap raw iterables with beam.pipeline | beam.Create(items) before passing them","Ensure the argument comes from a prior transform's output (a real PCollection)","Check for reassignments that overwrote the PCollection variable","Pass side-input data via beam.pvalue.AsList/AsDict/AsSingleton instead of as the main input"],"exampleFix":"// before\nmy_transform.expand([1, 2, 3])\n// after\npcoll = p | 'Create' >> beam.Create([1, 2, 3])\nmy_transform.expand(pcoll)","handlingStrategy":"type-guard","validationCode":"if not isinstance(arg, pvalue.PCollection):\n    arg = pipeline | 'CreateInput' >> beam.Create(arg)","typeGuard":"def is_pcollection(x):\n    return isinstance(x, pvalue.PCollection) and x.pipeline is not None","tryCatchPattern":"try:\n    result = my_transform.expand(arg)\nexcept error.TransformError as ex:\n    logger.error('bad expand input: %s', ex)\n    raise","preventionTips":["Always create inputs with beam.Create for raw data","Never pass plain lists/dicts as main inputs","Keep track of variable reassignments in pipeline code"],"tags":["python","apache-beam","ptransform","type-mismatch"],"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"}