apache/beam · error
invalid status for pardo %v: %v, want Active
Error message
invalid status for pardo %v: %v, want Active
What it means
ParDo.ProcessElement() only processes elements when the unit status is Active, i.e. after a successful StartBundle. The library throws this error when an element arrives outside an active bundle (before StartBundle, after FinishBundle, or when the unit is Broken), because per-element processing depends on the bundle-scoped reader and timer manager.
Source
Thrown at sdks/go/pkg/beam/core/runtime/exec/pardo.go:151
n.states.Set(n.ctx, metrics.StartBundle)
if err := MultiStartBundle(n.ctx, id, data, n.Out...); err != nil {
return n.fail(err)
}
// TODO(BEAM-3303): what to set for StartBundle/FinishBundle window and emitter timestamp?
if _, err := n.invokeDataFn(n.ctx, typex.NoFiringPane(), window.SingleGlobalWindow, mtime.ZeroTimestamp, n.Fn.StartBundleFn(), nil); err != nil {
return n.fail(err)
}
return nil
}
// ProcessElement processes each parallel element with the DoFn.
func (n *ParDo) ProcessElement(_ context.Context, elm *FullValue, values ...ReStream) error {
if n.status != Active {
return errors.Errorf("invalid status for pardo %v: %v, want Active", n.UID, n.status)
}
n.states.Set(n.ctx, metrics.ProcessBundle)
return n.processMainInput(&MainInput{Key: *elm, Values: values})
}
// processMainInput processes an element that has been converted into a
// MainInput. Splitting this away from ProcessElement allows other nodes to wrap
// a ParDo's ProcessElement functionality with their own construction of
// MainInputs.
func (n *ParDo) processMainInput(mainIn *MainInput) error {
n.TimerTracker.SetCurrentKey(mainIn)
elm := &mainIn.Key
// If the function observes windows or uses per window state, we must invoke it for each window.
// The expected fast path is that either there is a single window or the function doesn't observe
// windows, so we can optimize it by treating all windows as a single one.View on GitHub (pinned to 12126d8942)
Solutions
- Call StartBundle before processing any elements and FinishBundle before starting a new bundle.
- Discard and rebuild plans whose status became Broken after a failed bundle.
- When resuming split bundles, re-run StartBundle on the reconstructed plan before ProcessElement.
Example fix
// before
plan.Execute(ctx, id, mgr) // failed, plan now Broken
plan.Execute(ctx, id2, mgr) // ProcessElement -> invalid status
// after
if plan.getStatus() == exec.Broken {
plan, err = constructAndExecutePlanWithContext(ctx, ...)
} Defensive patterns
Strategy: validation
Validate before calling
if pardo.status != exec.Active {
return fmt.Errorf("pardo %v has no active bundle (status %v)", pardo.UID, pardo.status)
}
err := pardo.ProcessElement(ctx, elm, values...) Try / catch
err := plan.Execute(ctx, id, mgr)
if err != nil {
// plan is Broken; do not attempt more elements
plan = nil
return err
} Prevention
- Always pair StartBundle/FinishBundle around element processing.
- Stop feeding elements as soon as Execute returns an error.
- For split-bundle resume, ensure the resumed plan goes through StartBundle first.
When it happens
Trigger: Feeding elements to ParDo before StartBundle, after FinishBundle, or resuming element processing on a plan whose bundle failed and was marked Broken.
Common situations: Split-bundle resumption logic delivering elements to a stale plan; custom direct runners driving the SDF/plan API without the full bundle lifecycle.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- invalid status for pardo %v: %v, want Initializing
- invalid status for pardo %v: %v, want Up
- invalid status for plan %v: %v
- invalid status for combine %v: %v
- invalid status for precombine %v: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/4a2e71fbae697cff.
Report an issue: GitHub.