{"record":{"id":"2c5f9c1b9f75c9ba","repo":"apache/beam","slug":"the-pcollection-tuple-must-have-the-dicomio","errorCode":null,"errorMessage":"The PCollection tuple must have the DicomIO.ReadStudyMetadata.METADATA and DicomIO.ReadStudyMetadata.ERROR_MESSAGE tuple tags","messagePattern":"The PCollection tuple must have the DicomIO\\.ReadStudyMetadata\\.METADATA and DicomIO\\.ReadStudyMetadata\\.ERROR_MESSAGE 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/DicomIO.java","lineNumber":102,"sourceCode":"\n      /** Contains both the response and error outputs from the transformation. */\n      PCollectionTuple pct;\n\n      /**\n       * Create DicomIO.ReadStudyMetadata.Result from PCollectionTuple which contains the response\n       * (with METADATA and ERROR_MESSAGE tags).\n       *\n       * @param pct the pct\n       * @return the read result\n       * @throws IllegalArgumentException the illegal argument exception\n       */\n      static ReadStudyMetadata.Result of(PCollectionTuple pct) throws IllegalArgumentException {\n        if (pct.getAll()\n            .keySet()\n            .containsAll((Collection<?>) TupleTagList.of(METADATA).and(ERROR_MESSAGE))) {\n          return new ReadStudyMetadata.Result(pct);\n        } else {\n          throw new IllegalArgumentException(\n              \"The PCollection tuple must have the DicomIO.ReadStudyMetadata.METADATA \"\n                  + \"and DicomIO.ReadStudyMetadata.ERROR_MESSAGE tuple tags\");\n        }\n      }\n\n      private Result(PCollectionTuple pct) {\n        this.pct = pct;\n        this.readResponse = pct.get(METADATA);\n        this.failedReads = pct.get(ERROR_MESSAGE);\n      }\n\n      /**\n       * Gets failed reads.\n       *\n       * @return the failed reads\n       */\n      public PCollection<String> getFailedReads() {\n        return failedReads;","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/DicomIO.java#L84-L120","documentation":"DicomIO.ReadStudyMetadata.Result.of() validates that the incoming PCollectionTuple exposes exactly the expected TupleTags: DicomIO.ReadStudyMetadata.METADATA and DicomIO.ReadStudyMetadata.ERROR_MESSAGE. If the tuple lacks either tag, a Result cannot be constructed to represent the success/error split output, so an IllegalArgumentException is thrown. This is a fail-fast guard ensuring downstream writers can always call .get(METADATA) and .get(ERROR_MESSAGE).","triggerScenarios":"Calling ReadStudyMetadata.Result.of(pct) on a PCollectionTuple that was created without applying both METADATA and ERROR_MESSAGE TupleTags, or one built with different/renamed tags.","commonSituations":"Wiring a custom pipeline stage that produced only the metadata side; copy-pasting tag definitions so a locally re-declared TupleTag is not the same instance as the constant; refactoring that renamed tags while Result.of still checks the originals.","solutions":["Create the PCollectionTuple with both tags applied: pct.apply(METADATA, ...) and pct.apply(ERROR_MESSAGE, ...) before calling Result.of(pct)","Use the exact public constants DicomIO.ReadStudyMetadata.METADATA and .ERROR_MESSAGE rather than locally created TupleTag instances","Verify with pct.has(METADATA) && pct.has(ERROR_MESSAGE) before invoking of()","Check that your pipeline stage returns a PCollectionTuple, not a single PCollection"],"exampleFix":"// before\nPCollectionTuple pct = ...only metadata...;\nResult result = Result.of(pct);\n// after\nPCollectionTuple pct = pipeline.apply(new ReadStudyMetadata()).getOutput();\npct.apply(DicomIO.ReadStudyMetadata.METADATA, metadataPc);\npct.apply(DicomIO.ReadStudyMetadata.ERROR_MESSAGE, errorPc);\nResult result = Result.of(pct);","handlingStrategy":"validation","validationCode":"if (pct.has(DicomIO.ReadStudyMetadata.METADATA) && pct.has(DicomIO.ReadStudyMetadata.ERROR_MESSAGE)) {\n  Result r = DicomIO.ReadStudyMetadata.Result.of(pct);\n}","typeGuard":null,"tryCatchPattern":"try {\n  Result r = ReadStudyMetadata.Result.of(pct);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"PCollectionTuple missing METADATA/ERROR_MESSAGE tags\", e);\n}","preventionTips":["Always reference the public METADATA/ERROR_MESSAGE constants when building tuples","Let the ReadStudyMetadata transform produce the Result instead of hand-assembling PCollections","Add a pipeline-construction unit test asserting Result.of() succeeds"],"tags":["java","dicom","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-14T11:17:12.474Z"}