apache/beam · error
no units
Error message
no <nil> units
What it means
exec.NewPlan validates that no execution unit in the slice is nil before assembling roots and the data source. The library throws this error because a nil unit would panic later during plan execution; it is a defensive constructor check.
Solutions
- Filter or assert non-nil units before calling NewPlan.
- Check the code that builds the units slice: a failed unit construction usually returns an error that was swallowed.
- Add a guard in the plan-construction helper to return the earlier construction error instead of appending nil.
Example fix
// before
units := append(units, maybeUnit) // maybeUnit may be nil
plan, err := exec.NewPlan(id, units)
// after
if maybeUnit == nil {
return nil, fmt.Errorf("unit construction failed")
}
units := append(units, maybeUnit)
plan, err := exec.NewPlan(id, units) Defensive patterns
Strategy: validation
Validate before calling
for i, u := range units {
if u == nil {
return fmt.Errorf("unit %d is nil before NewPlan", i)
}
}
plan, err := exec.NewPlan(id, units) Try / catch
plan, err := exec.NewPlan(id, units)
if err != nil {
if strings.Contains(err.Error(), "no <nil> units") {
log.Printf("unit construction produced nil; check builder error handling")
}
return err
} Prevention
- Check the error return of every unit constructor before appending to the units slice.
- Never append a possibly-nil unit; return the construction error instead.
- Add unit-slice assertions in plan-building helper functions.
When it happens
Trigger: Passing a slice of execution units containing a nil entry to exec.NewPlan, usually because a preceding construction step (e.g. building a ParDo or DataSource) failed silently or a slice append skipped an assignment.
Common situations: Test code building unit lists dynamically (TestFlatten, TestMultiplex style); pipeline translation bugs where an optional transform produces no unit.
Related errors
- capacity of cache cannot be negative, got
- could not unmarshal iterable coder from
- could not unmarshal nullable coder from
- could not unmarshal sharded_key coder from
- empty pipeline
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/8d45c8a18628e963.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/exec/plan.go:61
// TODO: there can be more than 1 DataSource in a bundle.
source *DataSource
}
// NewPlan returns a new bundle execution plan from the given units.
func NewPlan(id string, units []Unit) (*Plan, error) {
var roots []Root
var pcols []*PCollection
var source *DataSource
bf := bundleFinalizer{
callbacks: []bundleFinalizationCallback{},
lastValidCallback: time.Now(),
}
var onTimers map[string]*ParDo
for _, u := range units {
if u == nil {
return nil, errors.Errorf("no <nil> units")
}
if r, ok := u.(Root); ok {
roots = append(roots, r)
}
if s, ok := u.(*DataSource); ok {
source = s
}
if p, ok := u.(*PCollection); ok {
pcols = append(pcols, p)
}
if pd, ok := u.(*ParDo); ok && pd.HasOnTimer() {
if onTimers == nil {
onTimers = map[string]*ParDo{}
}
onTimers[pd.PID] = pd
}
if p, ok := u.(needsBundleFinalization); ok {
p.AttachFinalizer(&bf)View on GitHub (pinned to 12126d8942)