apache/beam · error · RuntimeError

Unsupported transform

Error message

Unsupported transform {transform_id} of type {transform_proto.spec.urn}

What it means

The TrivialRunner (a single-process runner used mainly for testing) encountered a PTransform whose URN it does not know how to execute during execute_transform. It only implements a small set of transform types (like GBK/windowing); anything else raises RuntimeError. This means the pipeline contains a transform the trivial runner cannot simulate.

Solutions

  1. Run the pipeline with a real runner (DirectRunner, FlinkRunner, DataflowRunner) instead of TrivialRunner
  2. Check which transform_id/URN is unsupported and rewrite that stage using supported transforms (e.g. plain ParDo/GBK)
  3. Update/extend apache_beam: newer versions of trivial_runner support more URNs
  4. If intentional, implement the missing branch in TrivialRunner.execute_transform for that URN

Example fix

// before
pipeline.run(runner=TrivialRunner())
// after
pipeline.run(runner=DirectRunner())  # full transform support
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_URNS = {'beam:transform:group_by_key', 'beam:transform:pardo'}
for t in pipeline.proto.components.transforms.values():
    urn = t.spec.urn
    if urn and urn not in SUPPORTED_URNS:
        print('Unsupported by TrivialRunner:', t.unique_name, urn)
# use DirectRunner if any unsupported URN is found

Try / catch

try:
    pipeline.run(runner=TrivialRunner()).wait_until_finish()
except RuntimeError as e:
    if 'Unsupported transform' in str(e):
        logging.warning('TrivialRunner unsupported; falling back to DirectRunner')
        pipeline.run(runner=DirectRunner())
    else:
        raise

Prevention

When it happens

Trigger: Calling beam.pipeline.run() with runner=TrivialRunner (or run_portable_pipeline) on a pipeline containing transforms outside the supported set (e.g. custom composite URNs, side inputs, SDF) — anything falling into the else branch at trivial_runner.py:128.

Common situations: Using TrivialRunner to smoke-test a pipeline that uses transforms unsupported by the trivial runner; running a portable pipeline locally with an oversimplified runner; a Beam SDK change added a transform type the trivial runner doesn't handle yet.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/0fe3a77eb8af9294. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/runners/trivial_runner.py:128

          output_pcoll_id,
          sum([
              execution_state.get_pcollection_contents(pc)
              for pc in transform_proto.inputs.values()
          ], []))

    elif transform_proto.spec.urn == common_urns.executable_stage:
      # This is a collection of user DoFns.
      self.execute_executable_stage(transform_proto, execution_state)

    elif transform_proto.spec.urn == common_urns.primitives.GROUP_BY_KEY.urn:
      # Execute the grouping operation.
      self.group_by_key_and_window(
          only_element(transform_proto.inputs.values()),
          only_element(transform_proto.outputs.values()),
          execution_state)

    else:
      raise RuntimeError(
          f"Unsupported transform {transform_id}"
          " of type {transform_proto.spec.urn}")

  def execute_executable_stage(self, transform_proto, execution_state):
    # Stage here is like a mini pipeline, with PTransforms, PCollections, etc.
    # inside of it.
    stage = beam_runner_api_pb2.ExecutableStagePayload.FromString(
        transform_proto.spec.payload)
    if stage.side_inputs:
      # To support these we would need to make the side input PCollections
      # available over the state API before processing this bundle.
      raise NotImplementedError()

    # This is the set of transforms that were fused together.
    stage_transforms = {
        id: stage.components.transforms[id]
        for id in stage.transforms
    }

View on GitHub (pinned to 12126d8942)