apache/beam · error · RuntimeError
Start Bundle should not output any elements but got %s
Error message
Start Bundle should not output any elements but got %s
What it means
Beam DoFn lifecycle requires that start_bundle produces no output; only process() and finish_bundle() may emit elements. start_bundle_outputs raises RuntimeError if the start_bundle method returned anything other than None.
Source
Thrown at sdks/python/apache_beam/runners/common.py:1856
for timestamp in windowed_batch.timestamps:
watermark_estimator.observe_timestamp(timestamp)
if tag is None:
self.main_receivers.receive_batch(windowed_batch)
else:
self.tagged_receivers[tag].receive_batch(windowed_batch)
def _verify_batch_output(self, result):
if isinstance(result, (WindowedValue, TimestampedValue)):
raise TypeError(
f"Received {type(result).__name__} from DoFn that was "
"expected to produce a batch.")
def start_bundle_outputs(self, results):
"""Validate that start_bundle does not output any elements"""
if results is None:
return
raise RuntimeError(
'Start Bundle should not output any elements but got %s' % results)
def finish_bundle_outputs(self, results):
"""Dispatch the result of finish_bundle to the appropriate receivers.
A value wrapped in a TaggedOutput object will be unwrapped and
then dispatched to the appropriate indexed output.
"""
if results is None:
return
for result in results:
tag = None
if isinstance(result, TaggedOutput):
tag = result.tag
if not isinstance(tag, str):
raise TypeError('In %s, tag %s is not a string' % (self, tag))
result = result.valueView on GitHub (pinned to 12126d8942)
Solutions
- Remove the return/yield statements from start_bundle; perform only per-bundle setup (e.g. initializing clients).
- Move element emission to process() (per element) or finish_bundle() (per bundle, must yield WindowedValue).
- If side-effect setup is needed per window instead, restructure the pipeline with windowing-aware transforms.
Example fix
// before
def start_bundle(self):
yield 'warmup' # RuntimeError
// after
def start_bundle(self):
self.client = create_client() # setup only, no output Defensive patterns
Strategy: validation
Validate before calling
assert start_bundle() is None, 'start_bundle must not produce output'
Type guard
def is_valid_start_bundle_result(r):
return r is None Try / catch
try:
invoker.invoke_start_bundle()
except RuntimeError as e:
if 'Start Bundle should not output' in str(e):
raise ValueError('DoFn.start_bundle must not yield/return elements') from e
raise Prevention
- Keep start_bundle limited to side-effect-free or client-setup code with no return/yield.
- Code-review rule: any `yield` inside start_bundle is a bug.
- Run DoFn unit tests via the DirectRunner, which exercises start_bundle.
When it happens
Trigger: Implementing `def start_bundle(self)` in a DoFn with a `return some_value` (yield also counts, since a generator result is passed in) instead of returning None or having no return statement.
Common situations: Misunderstanding the lifecycle API and trying to emit warm-up/initializer elements in start_bundle; copying a finish_bundle pattern into start_bundle.
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
- Transform node %r was not replaced as expected.
- You cannot turn on runtime_type_check and performance_runtim
- A transform with label "%s" already exists in the pipeline.
- Finish Bundle should only output WindowedValue type but got
- Please specify InteractiveRunner when creating the Beam pipe
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/4b4f391ff269cdff.
Report an issue: GitHub.