apache/beam · error

invalid status for pardo %v: %v, want Up

Error message

invalid status for pardo %v: %v, want Up

What it means

ParDo.StartBundle() transitions the unit from Up to Active and requires status == Up. The library throws this error when StartBundle is invoked on a ParDo that has not been Up'd (status still Initializing) or that is already Active/Broken, because bundle-level state (reader, timer manager) can only be installed between Up and Active.

Source

Thrown at sdks/go/pkg/beam/core/runtime/exec/pardo.go:124

		return n.fail(err)
	}

	emitters, err := makeEmitters(n.Fn.ProcessElementFn(), n.Out)
	if err != nil {
		return n.fail(err)
	}
	n.emitters = emitters
	return nil
}

func (n *ParDo) AttachFinalizer(bf *bundleFinalizer) {
	n.bf = bf
}

// StartBundle does pre-bundle processing operation for the DoFn.
func (n *ParDo) StartBundle(ctx context.Context, id string, data DataContext) error {
	if n.status != Up {
		return errors.Errorf("invalid status for pardo %v: %v, want Up", n.UID, n.status)
	}
	n.status = Active
	n.reader = data.State
	n.timerManager = data.Data
	// Allocating contexts all the time is expensive, but we seldom re-write them,
	// and never accept modified contexts from users, so we will cache them per-bundle
	// per-unit, to avoid the constant allocation overhead.
	n.ctx = metrics.SetPTransformID(ctx, n.PID)

	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 {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Always execute the full lifecycle via Plan.Execute (Up -> StartBundle -> Process -> FinishBundle) instead of calling unit methods directly.
  2. Verify that StartBundle is called after Up and after FinishBundle returns the unit to Up status.
  3. Rebuild the plan if a previous bundle execution failed and set status to Broken.

Example fix

// before
for _, root := range plan.roots {
    root.StartBundle(ctx, id, data) // skipped Up
}
// after
if err := plan.Execute(ctx, id, data); err != nil {
    return err // Execute performs Up then StartBundle in order
}
Defensive patterns

Strategy: validation

Validate before calling

if pardo.status != exec.Up {
    return fmt.Errorf("pardo %v not ready for bundle (status %v)", pardo.UID, pardo.status)
}
err := pardo.StartBundle(ctx, id, data)

Try / catch

if err := plan.Execute(ctx, id, mgr); err != nil {
    if strings.Contains(err.Error(), "want Up") {
        plan, err = constructAndExecutePlanWithContext(ctx, id, units, mgr)
    }
}

Prevention

When it happens

Trigger: Calling StartBundle before Up, calling StartBundle twice for the same bundle, or calling StartBundle after FinishBundle transitioned status back but the unit was actually Broken.

Common situations: Custom runners or test harnesses driving the exec plan lifecycle manually out of order; reusing a plan across bundles when a previous bundle failed mid-way leaving status Broken.

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


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