apache/beam · error

invalid status , want Active

Error message

invalid status %v, want Active

What it means

ProcessSizedElementsAndRestrictions.ProcessElement delegates to the underlying ParDo, and only permits this when the ParDo is in status Active. If the ParDo has not been started (setUp) or has already been torn down, processing aborts with this status check error.

Solutions

  1. Ensure StartBundle (unit Up()) is called on the transform before processing elements
  2. Ensure ProcessElement is not called after FinishBundle/Down for the bundle
  3. Fix the executor/lifecycle ordering so SDF transforms follow the standard Up → Process → Down sequence
  4. If embedding Beam Go exec units directly, verify your driver sets status correctly before dispatching elements

Example fix

// before: processing before bundle start
for _, elm := range elements {
    sdf.ProcessElement(ctx, elm) // PDo not Active yet
}
plan.Execute(ctx) // never called first
// after
plan.Execute(ctx) // performs Up() on all units first
for _, elm := range elements {
    sdf.ProcessElement(ctx, elm)
}
Defensive patterns

Strategy: validation

Validate before calling

// Only process elements within the Execute lifecycle
if err := plan.Execute(ctx); err != nil { return err } // Up() runs inside first

Try / catch

if err := plan.Execute(ctx); err != nil {
    if strings.Contains(err.Error(), "invalid status") {
        log.Printf("lifecycle violation: %v", err)
    }
    plan.Down(); return err
}

Prevention

When it happens

Trigger: Calling ProcessElement on ProcessSizedElementsAndRestrictions when n.PDo.status != Active — i.e. before StartBundle/Up() initialized the ParDo, or after Down()/FinishBundle deactivated it.

Common situations: Harness lifecycle bugs where elements are processed before the bundle starts or after teardown; reusing a unit across bundles without re-initialization; custom runners invoking ProcessElement out of order.

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/396def359f26e8bb. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/runtime/exec/sdf.go:499

//		Elm: *FullValue {
//			Elm:  *FullValue (KV input) or InputType (single-element input)
//			Elm2: *FullValue {
//				Elm: Restriction
//				Elm2: Watermark estimator state
//		 	}
//		}
//		Elm2: float64 (size)
//		Windows
//		Timestamps
//	}
//
// ProcessElement then creates a restriction tracker from the stored restriction
// and processes each element using the underlying ParDo and adding the
// restriction tracker to the normal invocation. Sizing information is present
// but currently ignored. Output is forwarded to the underlying ParDo's outputs.
func (n *ProcessSizedElementsAndRestrictions) ProcessElement(ctx context.Context, elm *FullValue, values ...ReStream) error {
	if n.PDo.status != Active {
		err := errors.Errorf("invalid status %v, want Active", n.PDo.status)
		return errors.WithContextf(err, "%v", n)
	}

	// Package our element in a MainInput struct so the underlying ParDo can
	// process it.
	mainIn := &MainInput{
		Values: values,
	}

	// For the key, the way we fill it out depends on whether the input element
	// is a KV or single-element. Single-elements might have been lifted out of
	// their FullValue if they were decoded, so we need to have a case for that.
	// Also, we use the top-level windows and timestamp.
	// TODO(https://github.com/apache/beam/issues/20196): Optimize this so it's decided in exec/translate.go
	// instead of checking per-element.
	if userElm, ok := elm.Elm.(*FullValue).Elm.(*FullValue); ok {
		mainIn.Key = FullValue{
			Elm:       userElm.Elm,

View on GitHub (pinned to 12126d8942)