{"record":{"id":"66dd03b9b249843d","repo":"apache/beam","slug":"panic-formatpardoerror-dofn-len-ret-3","errorCode":null,"errorMessage":"panic(formatParDoError(dofn, len(ret), 3))","messagePattern":"panic\\(formatParDoError\\(dofn, len\\(ret\\), 3\\)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/pardo.go","lineNumber":451,"sourceCode":"\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))\n\t}\n\treturn ret[0], ret[1], ret[2], ret[3]\n}\n\n// ParDo5 inserts a ParDo with 5 outputs into the pipeline.\nfunc ParDo5(s Scope, dofn any, col PCollection, opts ...Option) (PCollection, PCollection, PCollection, PCollection, PCollection) {\n\tret := MustN(TryParDo(s, dofn, col, opts...))\n\tif len(ret) != 5 {\n\t\tpanic(formatParDoError(dofn, len(ret), 5))","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/pardo.go#L433-L469","documentation":"ParDo3 applies a DoFn expected to produce exactly 3 outputs. If TryParDo returns a different number of PCollections (because the DoFn's ProcessElement signature does not emit exactly 3 values), the library panics with formatParDoError, a concise diagnostic naming the DoFn, the actual output count, and the expected count.","triggerScenarios":"Calling beam.ParDo3 with a DoFn whose ProcessElement returns/emits fewer or more than 3 outputs (e.g. a DoFn with 2 emit parameters or return values).","commonSituations":"Refactoring a DoFn to add/remove an output without updating the ParDoN variant; copying a single-output DoFn into a multi-output pipeline; mismatching emit function count in the DoFn struct versus the chosen ParDoN helper.","solutions":["Check the DoFn's ProcessElement signature and make it emit exactly 3 outputs (3 emit fields or 3 return values).","Or switch to the matching helper: use ParDo2/ParDo4/etc., or ParDoN/TryParDo for arbitrary output counts.","Read the panic message from formatParDoError, which names the DoFn type, actual count, and expected count, to pinpoint the mismatch."],"exampleFix":"// before: DoFn emits only 2 outputs but ParDo3 is used\nfunc (f *splitFn) ProcessElement(kv beam.KV) (string, int) { ... }\nbeam.ParDo3(s, &splitFn{}, col)\n\n// after: emit exactly 3 outputs\nfunc (f *splitFn) ProcessElement(kv beam.KV) (string, string, int) { ... }\nbeam.ParDo3(s, &splitFn{}, col)","handlingStrategy":"validation","validationCode":"// verify DoFn output count before choosing ParDo3\nif outputsOfMyDoFn != 3 {\n    log.Fatalf(\"DoFn must emit exactly 3 outputs, got %d\", outputsOfMyDoFn)\n}","typeGuard":null,"tryCatchPattern":"// Go panics are not catchable by recover in another goroutine; wrap pipeline construction:\nfunc buildPipeline() (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"pardo construction failed: %v\", r)\n        }\n    }()\n    beam.ParDo3(s, &splitFn{}, col)\n    return nil\n}","preventionTips":["Count emit fields/return values on the DoFn before selecting the ParDoN variant","Use TryParDo for programmatic output-count handling","Keep DoFn output arity stable; when changing it, update all ParDoN call sites"],"tags":["go","apache-beam","pardo","panic","signature-mismatch"],"backgroundTag":"invalid-argument-value","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"}