{"record":{"id":"e9f5eb537312433e","repo":"apache/beam","slug":"panic-formatpardoerror-dofn-len-ret-2","errorCode":null,"errorMessage":"panic(formatParDoError(dofn, len(ret), 2))","messagePattern":"panic\\(formatParDoError\\(dofn, len\\(ret\\), 2\\)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/pardo.go","lineNumber":442,"sourceCode":"// runner to \"flatten out\" all the compositions into highly optimized stages.\n//\n// See https://beam.apache.org/documentation/programming-guide/#pardo\n// for the web documentation for ParDo\nfunc ParDo(s Scope, dofn any, col PCollection, opts ...Option) PCollection {\n\tret := MustN(TryParDo(s, dofn, col, opts...))\n\tif len(ret) != 1 {\n\t\tpanic(formatParDoError(dofn, len(ret), 1))\n\t}\n\treturn ret[0]\n}\n\n// TODO(herohde) 6/1/2017: add windowing aspects to above documentation.\n\n// ParDo2 inserts a ParDo with 2 outputs into the pipeline.\nfunc ParDo2(s Scope, dofn any, col PCollection, opts ...Option) (PCollection, PCollection) {\n\tret := MustN(TryParDo(s, dofn, col, opts...))\n\tif len(ret) != 2 {\n\t\tpanic(formatParDoError(dofn, len(ret), 2))\n\t}\n\treturn ret[0], ret[1]\n}\n\n// ParDo3 inserts a ParDo with 3 outputs into the pipeline.\nfunc ParDo3(s Scope, dofn any, col PCollection, opts ...Option) (PCollection, PCollection, PCollection) {\n\tret := MustN(TryParDo(s, dofn, col, opts...))\n\tif len(ret) != 3 {\n\t\tpanic(formatParDoError(dofn, len(ret), 3))\n\t}\n\treturn ret[0], ret[1], ret[2]\n}\n\n// ParDo4 inserts a ParDo with 4 outputs into the pipeline.\nfunc ParDo4(s Scope, dofn any, col PCollection, opts ...Option) (PCollection, PCollection, PCollection, PCollection) {\n\tret := MustN(TryParDo(s, dofn, col, opts...))\n\tif len(ret) != 4 {\n\t\tpanic(formatParDoError(dofn, len(ret), 4))","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/pardo.go#L424-L460","documentation":"ParDo2 applies a ParDo transform that must produce exactly two output PCollections. If TryParDo returns a count other than 2, it panics with a formatted ParDo error stating the dofn, actual count, and expected count of 2.","triggerScenarios":"Calling beam.ParDo2 with a DoFn that emits only one output or three+ outputs (wrong number of emit functions or return values).","commonSituations":"Adding or removing an output emitter from a DoFn without switching from ParDo2 to ParDo/ParDo3, or copy-pasting a DoFn between call sites with different arity helpers.","solutions":["Give the DoFn exactly two outputs (two emit funcs or two return values)","Use ParDo for one output or ParDo3 for three outputs to match the DoFn","Check the counts in the panic message and align the helper variant with the DoFn signature"],"exampleFix":"// before\nbeam.ParDo2(s, func(x int, emit func(int)) {...}, col) // 1 output, expects 2\n// after\nbeam.ParDo(s, func(x int, emit func(int)) {...}, col)","handlingStrategy":"type-guard","validationCode":"// A ParDo2 DoFn must produce exactly two outputs","typeGuard":"func isTwoOutputDoFn(fn any) bool {\n    t := reflect.TypeOf(fn)\n    for t.Kind() == reflect.Ptr {\n        t = t.Elem()\n    }\n    m, ok := t.MethodByName(\"ProcessElement\")\n    if !ok { return false }\n    numEmit := 0\n    for i := 0; i < m.Type.NumIn(); i++ {\n        if m.Type.In(i).Kind() == reflect.Func { numEmit++ }\n    }\n    return numEmit == 2 || m.Type.NumOut() == 2\n}","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        err = fmt.Errorf(\"ParDo2 arity mismatch: %v\", r)\n    }\n}()","preventionTips":["Ensure DoFns passed to ParDo2 emit exactly two outputs (two emits or two returns)","Update the helper variant whenever a DoFn's output count changes","Add small pipeline tests per transform to catch arity drift at construction time"],"tags":["go","beam","pardo","arity"],"backgroundTag":"unexpected-response-shape","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}