{"record":{"id":"654a012d679cf1a7","repo":"apache/beam","slug":"the-pcollection-tuple-must-have-the-fhirio-read-out-and","errorCode":null,"errorMessage":"The PCollection tuple must have the FhirIO.Read.OUT and FhirIO.Read.DEAD_LETTER tuple tags","messagePattern":"The PCollection tuple must have the FhirIO\\.Read\\.OUT and FhirIO\\.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/FhirIO.java","lineNumber":480,"sourceCode":"      private PCollection<String> resources;\n\n      private PCollection<HealthcareIOError<String>> failedReads;\n\n      /** The Pct. */\n      PCollectionTuple pct;\n\n      /**\n       * Create FhirIO.Read.Result form PCollectionTuple with OUT and DEAD_LETTER tags.\n       *\n       * @param pct the pct\n       * @return the read result\n       * @throws IllegalArgumentException the illegal argument exception\n       */\n      static FhirIO.Read.Result of(PCollectionTuple pct) throws IllegalArgumentException {\n        if (pct.has(OUT) && pct.has(DEAD_LETTER)) {\n          return new FhirIO.Read.Result(pct);\n        } else {\n          throw new IllegalArgumentException(\n              \"The PCollection tuple must have the FhirIO.Read.OUT \"\n                  + \"and FhirIO.Read.DEAD_LETTER tuple tags\");\n        }\n      }\n\n      private Result(PCollectionTuple pct) {\n        this.pct = pct;\n        this.resources = pct.get(OUT);\n        this.failedReads =\n            pct.get(DEAD_LETTER).setCoder(HealthcareIOErrorCoder.of(StringUtf8Coder.of()));\n      }\n\n      /**\n       * Gets failed reads.\n       *\n       * @return the failed reads\n       */\n      public PCollection<HealthcareIOError<String>> getFailedReads() {","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/FhirIO.java#L462-L498","documentation":"FhirIO.Read.Result.of() requires the PCollectionTuple to contain both the FhirIO.Read.OUT and FhirIO.Read.DEAD_LETTER TupleTags, because a FHIR read produces successfully parsed resources on OUT and failures on DEAD_LETTER. If either tag is missing, the Result wrapper cannot function and an IllegalArgumentException is thrown immediately. This fail-fast check prevents later NullPointerExceptions when callers retrieve the output PCollections.","triggerScenarios":"Calling FhirIO.Read.Result.of(pct) with a PCollectionTuple that lacks either the OUT or DEAD_LETTER tag — e.g. a tuple assembled from a custom transform that only emits the OUT collection.","commonSituations":"Manually constructing the PCollectionTuple instead of using the return value of the FhirIO.Read transform; renaming or re-declaring TupleTags so the contains check fails; adapting code from another IO connector whose Result.of only needed one tag.","solutions":["Apply both tags to the tuple: pct.apply(FhirIO.Read.OUT, resources) and pct.apply(FhirIO.Read.DEAD_LETTER, failures) before Result.of(pct)","Use the FhirIO.Read transform's returned Result directly instead of rebuilding a PCollectionTuple","Reference the exact constants FhirIO.Read.OUT and FhirIO.Read.DEAD_LETTER when populating the tuple","Guard the call with pct.has(OUT) && pct.has(DEAD_LETTER) during development"],"exampleFix":"// before\nPCollectionTuple pct = PCollectionTuple.of(FhirIO.Read.OUT, resources);\nFhirIO.Read.Result r = FhirIO.Read.Result.of(pct); // throws\n// after\nPCollectionTuple pct = new PCollectionTuple(pipeline);\npct.put(FhirIO.Read.OUT, resources);\npct.put(FhirIO.Read.DEAD_LETTER, failures);\nFhirIO.Read.Result r = FhirIO.Read.Result.of(pct);","handlingStrategy":"validation","validationCode":"if (pct.has(FhirIO.Read.OUT) && pct.has(FhirIO.Read.DEAD_LETTER)) {\n  FhirIO.Read.Result r = FhirIO.Read.Result.of(pct);\n}","typeGuard":null,"tryCatchPattern":"try {\n  FhirIO.Read.Result r = FhirIO.Read.Result.of(pct);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"Tuple missing FhirIO.Read.OUT/DEAD_LETTER tags\", e);\n}","preventionTips":["Use FhirIO.Read's returned Result rather than reconstructing it","Keep TupleTags as the library-provided constants","Write a pipeline-construction smoke test for FhirIO.Read wiring"],"tags":["java","fhir","healthcare","pcollection-tuple"],"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"}