apache/beam · error
panic(formatParDoError(dofn, len(ret), 0))
Error message
panic(formatParDoError(dofn, len(ret), 0))
What it means
ParDo0 applies a ParDo transform that must produce exactly zero output PCollections. After TryParDo succeeds, if the number of returned PCollections is not 0, it panics with a formatted ParDo error describing the dofn and the actual vs expected output count.
Source
Thrown at sdks/go/pkg/beam/pardo.go:137
var ret []PCollection
for _, out := range edge.Output {
c := PCollection{out.To}
c.SetCoder(NewCoder(c.Type()))
ret = append(ret, c)
}
return ret, nil
}
// ParDoN inserts a ParDo with any number of outputs into the pipeline.
func ParDoN(s Scope, dofn any, col PCollection, opts ...Option) []PCollection {
return MustN(TryParDo(s, dofn, col, opts...))
}
// ParDo0 inserts a ParDo with zero output transform into the pipeline.
func ParDo0(s Scope, dofn any, col PCollection, opts ...Option) {
ret := MustN(TryParDo(s, dofn, col, opts...))
if len(ret) != 0 {
panic(formatParDoError(dofn, len(ret), 0))
}
}
// ParDo is the core element-wise PTransform in Apache Beam, invoking a
// user-specified function on each of the elements of the input PCollection
// to produce zero or more output elements, all of which are collected into
// the output PCollection. Use one of the ParDo variants for a different
// number of output PCollections. The PCollections do not need to have the
// same types.
//
// Elements are processed independently, and possibly in parallel across
// distributed cloud resources. The ParDo processing style is similar to what
// happens inside the "Mapper" or "Reducer" class of a MapReduce-style
// algorithm.
//
// # DoFns
//
// The function to use to process each element is specified by a DoFn, either asView on GitHub (pinned to 12126d8942)
Solutions
- Change the DoFn to return no values (side-effect-only, e.g. via an output sink)
- Use beam.ParDo instead if the DoFn legitimately produces one output
- Match the ParDo0/ParDo/ParDoN variant to the DoFn's actual return arity
Example fix
// before
beam.ParDo0(s, func(x string) string { return x }, col) // 1 output, expects 0
// after
beam.ParDo(s, func(x string) string { return x }, col) Defensive patterns
Strategy: type-guard
Validate before calling
// Check DoFn signature arity before applying // A ParDo0 DoFn must produce no outputs (no return values beyond error conventions)
Type guard
func isZeroOutputDoFn(fn any) bool {
t := reflect.TypeOf(fn)
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
m, ok := t.MethodByName("ProcessElement")
if !ok { return false }
// heuristic: count emit params and return values against expected outputs
return m.Type.NumOut() == 0
} Try / catch
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("ParDo0 arity mismatch: %v", r)
}
}() Prevention
- Match the ParDo0/ParDo/ParDoN helper to the DoFn's output count
- Re-check call sites after changing a DoFn's return signature
- Write pipeline-construction tests that exercise each transform once
When it happens
Trigger: Calling beam.ParDo0 with a DoFn whose signature yields one or more output PCollections (e.g. a function that returns a value) instead of returning nothing.
Common situations: Reusing a DoFn written for beam.ParDo/ParDo2 with ParDo0, or changing a DoFn's return signature after switching the apply call, causing a count mismatch.
Related errors
- panic(formatParDoError(dofn, len(ret), 1))
- panic(formatParDoError(dofn, len(ret), 2))
- unable to decode ParDoPayload for %v
- %v cannot bind to %v
- CreateWatermarkEstimator fn %v has unexpected number of para
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/01da96fc4cbdc4b2.
Report an issue: GitHub.