{"record":{"id":"daaffa8ed061b8d2","repo":"apache/beam","slug":"transform-full-label-was-applied-to-the-output-of-producer","errorCode":null,"errorMessage":"Transform \"{full_label}\" was applied to the output of \"{producer_label}\" but \"{producer_label.split(\"/\")[-1]}\" produces no PCollections.","messagePattern":"Transform \"(.+?)\" was applied to the output of \"(.+?)\" but \"(.+?)\" produces no PCollections\\.","errorType":"exception","errorClass":"TypeCheckError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/pipeline.py","lineNumber":851,"sourceCode":"              current.add_output(pc, tag)\n          continue\n\n        # If there is already a tag with the same name, increase a counter for\n        # the name. This can happen, for example, when a composite outputs a\n        # list of PCollections where all the tags are None.\n        base = tag\n        counter = 0\n        while tag in current.outputs:\n          counter += 1\n          tag = '%s_%d' % (base, counter)\n\n        current.add_output(result, tag)\n\n      if (type_options is not None and\n          type_options.type_check_strictness == 'ALL_REQUIRED' and\n          transform.get_type_hints().output_types is None):\n        ptransform_name = '%s(%s)' % (transform.__class__.__name__, full_label)\n        raise TypeCheckError(\n            'Pipeline type checking is enabled, however no '\n            'output type-hint was found for the '\n            'PTransform %s' % ptransform_name)\n    finally:\n      self.transforms_stack.pop()\n    return pvalueish_result\n\n  def _assert_not_applying_PDone(\n      self,\n      pvalueish: Optional[pvalue.PValue],\n      transform: ptransform.PTransform):\n    if isinstance(pvalueish, pvalue.PDone) and isinstance(transform, ParDo):\n      # If the input is a PDone, we cannot apply a ParDo transform.\n      full_label = self._current_transform().full_label\n      producer_label = pvalueish.producer.full_label\n      raise TypeCheckError(\n          f'Transform \"{full_label}\" was applied to the output of '\n          f'\"{producer_label}\" but \"{producer_label.split(\"/\")[-1]}\" '","sourceCodeStart":833,"sourceCodeEnd":869,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/pipeline.py#L833-L869","documentation":"This TypeCheckError is raised when a PTransform is applied to the output of a transform that produces no PCollections — i.e. the producer's output is a PDone (a placeholder meaning 'nothing left to do'). Apache Beam throws it because applying a downstream transform to a PDone result is meaningless; PDone cannot be consumed by another transform.","triggerScenarios":"Calling pipeline.apply(some_par_do, pdone_value) where pdone_value is the result of a transform returning PDone, e.g. writing to a sink or calling custom_write().apply(...) chain after a write.","commonSituations":"Chaining a .apply() onto the result of a WriteToText/WriteToBigQuery (which yields PDone); mistakenly treating the return of pipeline.run() or a sink write as a PCollection.","solutions":["Remove the extra .apply() after the write/sink transform and apply further transforms to the PCollection before writing","Capture the PCollection before the sink if you need to apply more transforms to the same data","If you truly need a downstream effect, wrap logic in the DoFn itself rather than applying a transform to PDone"],"exampleFix":"// before\n_ = (pcoll | 'Write' >> beam.io.WriteToText('out') | 'More' >> beam.Map(fn))\n// after\ntransformed = pcoll | 'More' >> beam.Map(fn)\ntransformed | 'Write' >> beam.io.WriteToText('out')","handlingStrategy":"validation","validationCode":"if isinstance(producer_result, apache_beam.pvalue.PDone):\n    raise ValueError('Cannot apply a transform to a PDone output')","typeGuard":"from apache_beam.pvalue import PValue\n\ndef is_pcollection(x):\n    return isinstance(x, PValue) and not isinstance(x, type(__import__('apache_beam').pvalue.PDone)())","tryCatchPattern":"try:\n    result = pdone | beam.Map(fn)\nexcept apache_beam.TypeCheckError as e:\n    logging.error('Cannot chain transform after sink: %s', e)","preventionTips":["Never chain .apply() on the return of Write transforms","Keep the PCollection reference before the sink for further transforms","Enable type checking during development to catch PDone misuse early"],"tags":["python","apache-beam","pipeline","typecheck"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}