{"record":{"id":"bc9533f7747fc9a8","repo":"apache/beam","slug":"the-pcollection-tuple-must-have-the-hl7v2io-read-out-and","errorCode":null,"errorMessage":"The PCollection tuple must have the HL7v2IO.Read.OUT and HL7v2IO.Read.DEAD_LETTER tuple tags","messagePattern":"The PCollection tuple must have the HL7v2IO\\.Read\\.OUT and HL7v2IO\\.Read\\.DEAD_LETTER tuple tags","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/HL7v2IO.java","lineNumber":280,"sourceCode":"   * href=https://cloud.google.com/healthcare/docs/reference/rest/v1/projects.locations.datasets.hl7V2Stores.messages/list></a>.\n   */\n  public static class Read extends PTransform<PCollection<String>, Read.Result> {\n\n    public Read() {}\n\n    /**\n     * The type Result includes {@link PCollection} of {@link HL7v2Message} objects for successfully\n     * read results and {@link PCollection} of {@link HealthcareIOError} objects for failed reads.\n     */\n    public static class Result extends HL7v2ReadResult<String, HL7v2Message> {\n\n      public static Result of(PCollectionTuple pct) throws IllegalArgumentException {\n        if (pct.getAll()\n            .keySet()\n            .containsAll(TupleTagList.of(Read.OUT).and(DEAD_LETTER).getAll())) {\n          return new Result(pct);\n        } else {\n          throw new IllegalArgumentException(\n              \"The PCollection tuple must have the HL7v2IO.Read.OUT \"\n                  + \"and HL7v2IO.Read.DEAD_LETTER tuple tags\");\n        }\n      }\n\n      private Result(PCollectionTuple pct) {\n        super(pct);\n        this.out = Read.OUT;\n        this.messages = pct.get(OUT).setCoder(HL7v2MessageCoder.of());\n        this.failedReads =\n            pct.get(DEAD_LETTER).setCoder(HealthcareIOErrorCoder.of(StringUtf8Coder.of()));\n      }\n    }\n\n    /** The tag for the main output of HL7v2 Messages. */\n    public static final TupleTag<HL7v2Message> OUT = new TupleTag<HL7v2Message>() {};\n\n    /** The tag for the deadletter output of HL7v2 Messages. */","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/HL7v2IO.java#L262-L298","documentation":"HL7v2IO.Read.Result.of() checks that the key set of the given PCollectionTuple contains all TupleTags of HL7v2IO.Read.OUT and HL7v2IO.Read.DEAD_LETTER. The Result wrapper is only meaningful for tuples that carry both the main output and the dead-letter output of the HL7v2IO.Read transform, so an incomplete tuple is rejected with IllegalArgumentException at authoring time.","triggerScenarios":"Calling HL7v2IO.Read.of(pct) / Result.of(pct) with a tuple missing the OUT tag, missing the DEAD_LETTER tag, or using tags declared elsewhere (custom TupleTag instances) instead of the static constants on HL7v2IO.Read.","commonSituations":"Hand-assembling a PCollectionTuple instead of taking the output of hl7v2IO.read(); renaming or redefining the TupleTags locally; wiring only the successful messages and skipping the dead-letter output.","solutions":["Populate the tuple with pcollections keyed by HL7v2IO.Read.OUT and HL7v2IO.Read.DEAD_LETTER before calling Result.of.","Use the exact static TupleTag constants from HL7v2IO.Read rather than new TupleTag<> instances with the same id string.","Prefer building the tuple from the transform's expand() output, which is guaranteed to carry both tags."],"exampleFix":"// before\nPCollectionTuple pct = PCollectionTuple.of(new TupleTag<HL7v2Message>(\"out\"), msgs);\nHL7v2IO.Read.Result.of(pct); // throws\n\n// after\nPCollectionTuple pct = PCollectionTuple.of(HL7v2IO.Read.OUT, msgs,\n    HL7v2IO.Read.DEAD_LETTER, failedMsgs);\nHL7v2IO.Read.Result.of(pct);","handlingStrategy":"validation","validationCode":"if (!pct.getAll().keySet().containsAll(TupleTagList.of(HL7v2IO.Read.OUT).and(HL7v2IO.Read.DEAD_LETTER).getAll())) {\n  throw new IllegalArgumentException(\"HL7v2IO.Read tuple missing OUT or DEAD_LETTER\");\n}","typeGuard":"boolean isHl7v2ReadResult(PCollectionTuple pct) {\n  return pct.getAll().keySet().containsAll(\n      TupleTagList.of(HL7v2IO.Read.OUT).and(HL7v2IO.Read.DEAD_LETTER).getAll());\n}","tryCatchPattern":"try {\n  HL7v2IO.Read.Result r = HL7v2IO.Read.Result.of(pct);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"Tuple tags do not match HL7v2IO.Read contract\", e);\n}","preventionTips":["Use HL7v2IO.Read.OUT and HL7v2IO.Read.DEAD_LETTER constants when calling pct.get().","Don't confuse HL7v2IO.Read tags with HL7v2IO.HL7v2Read tags.","Wire the dead-letter output even if you only discard it."],"tags":["java","apache-beam","google-cloud-healthcare","hl7v2","illegal-argument"],"backgroundTag":"missing-required-argument","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"}