apache/beam · error · TypeError

Input to Impulse transform must be a PBegin but found

Error message

Input to Impulse transform must be a PBegin but found %s

What it means

Impulse is a pipeline-root primitive that must take a PBegin as its input. Beam raises TypeError when something other than PBegin (e.g. a PCollection) is fed into the Impulse transform, because Impulse can only start a pipeline, not consume an existing PCollection.

Solutions

  1. Apply Impulse to the pipeline root: beam.Impulse() must be the first transform: p | beam.Impulse() | ...
  2. Remove Impulse from mid-pipeline positions; use an existing PCollection directly.
  3. If you need to synthesize elements mid-pipeline, use beam.Create([...]) on the pipeline instead.

Example fix

// before
result = pcoll | beam.Impulse() | beam.Map(lambda x: b'data')
// after
result = p | beam.Impulse() | beam.Map(lambda x: b'data')
Defensive patterns

Strategy: type-guard

Validate before calling

import apache_beam as beam
from apache_beam import pvalue
assert isinstance(root, pvalue.PBegin), 'Impulse must be applied to the pipeline root'

Type guard

def can_apply_impulse(x) -> bool:
    from apache_beam import pvalue
    return isinstance(x, pvalue.PBegin)

Try / catch

try:
    out = source | beam.Impulse()
except TypeError as e:
    if 'must be a PBegin' in str(e):
        out = pipeline | beam.Impulse()
    else:
        raise

Prevention

When it happens

Trigger: Applying beam.Impulse() to a PCollection (e.g. pcoll | beam.Impulse()) instead of to the pipeline object; composing Impulse as a downstream step inside another transform whose input is a PCollection.

Common situations: Misplacing Impulse mid-pipeline in test helpers; copy-paste from examples where Impulse was the first stage; trying to 'restart' a pipeline from within a branch.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/transforms/core.py:4315

  @staticmethod
  def _create_source_from_iterable(values, coder):
    return Create._create_source(list(map(coder.encode, values)), coder)

  @staticmethod
  def _create_source(serialized_values, coder):
    # type: (typing.Any, typing.Any) -> create_source._CreateSource
    from apache_beam.transforms.create_source import _CreateSource

    return _CreateSource(serialized_values, coder)


@typehints.with_output_types(bytes)
class Impulse(PTransform):
  """Impulse primitive."""
  def expand(self, pbegin):
    if not isinstance(pbegin, pvalue.PBegin):
      raise TypeError(
          'Input to Impulse transform must be a PBegin but found %s' % pbegin)
    return pvalue.PCollection(pbegin.pipeline, element_type=bytes)

  def get_windowing(self, inputs):
    # type: (typing.Any) -> Windowing
    return Windowing(GlobalWindows())

  def infer_output_type(self, unused_input_type):
    return bytes

  def to_runner_api_parameter(self, unused_context):
    # type: (PipelineContext) -> typing.Tuple[str, None]
    return common_urns.primitives.IMPULSE.urn, None

  @staticmethod
  @PTransform.register_urn(common_urns.primitives.IMPULSE.urn, None)
  def from_runner_api_parameter(
      unused_ptransform, unused_parameter, unused_context):

View on GitHub (pinned to 12126d8942)