{"record":{"id":"0d10fb374e257933","repo":"apache/beam","slug":"tupletag-already-present-in-this-tuple","errorCode":null,"errorMessage":"TupleTag already present in this tuple","messagePattern":"TupleTag already present in this tuple","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/values/PCollectionTuple.java","lineNumber":299,"sourceCode":"  /**\n   * <b><i>For internal use only; no backwards-compatibility guarantees.</i></b>\n   *\n   * <p>Returns a {@link PCollectionTuple} with each of the given tags mapping to a new output\n   * {@link PCollection}.\n   *\n   * <p>For use by primitive transformations only.\n   */\n  @Internal\n  public static PCollectionTuple ofPrimitiveOutputsInternal(\n      Pipeline pipeline,\n      TupleTagList outputTags,\n      Map<TupleTag<?>, Coder<?>> coders,\n      WindowingStrategy<?, ?> windowingStrategy,\n      IsBounded isBounded) {\n    Map<TupleTag<?>, PCollection<?>> pcollectionMap = new LinkedHashMap<>();\n    for (TupleTag<?> outputTag : outputTags.tupleTags) {\n      if (pcollectionMap.containsKey(outputTag)) {\n        throw new IllegalArgumentException(\"TupleTag already present in this tuple\");\n      }\n\n      // In fact, `token` and `outputCollection` should have\n      // types TypeDescriptor<T> and PCollection<T> for some\n      // unknown T. It is safe to create `outputCollection`\n      // with type PCollection<Object> because it has the same\n      // erasure as the correct type. When a transform adds\n      // elements to `outputCollection` they will be of type T.\n      @SuppressWarnings(\"unchecked\")\n      PCollection<?> outputCollection =\n          PCollection.createPrimitiveOutputInternal(\n                  pipeline, windowingStrategy, isBounded, (Coder) coders.get(outputTag))\n              .setTypeDescriptor(outputTag.getTypeDescriptor());\n\n      pcollectionMap.put(outputTag, outputCollection);\n    }\n    return new PCollectionTuple(pipeline, pcollectionMap);\n  }","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/values/PCollectionTuple.java#L281-L317","documentation":"PCollectionTuple.ofPrimitiveOutputsInternal builds its internal map of output tags to PCollections and throws IllegalArgumentException when the same TupleTag appears twice in the provided TupleTagList. Beam requires each output tag in a tuple to be unique so that tags can act as unambiguous keys for mapping outputs. This guard prevents silently overwriting or aliasing a tagged output.","triggerScenarios":"Calling PCollectionTuple.ofPCollections / PCollectionTuple.of (which routes into ofPrimitiveOutputsInternal) with a TupleTagList or set of (tag, PCollection) pairs in which the same TupleTag instance or an equal TupleTag (same id) is supplied more than once, e.g. PCollectionTuple.of(tag1, pc1).and(tag1, pc2).","commonSituations":"Reusing a single TupleTag field for multiple outputs in a ParDo with several side outputs; programmatically generating tags in a loop but reusing one tag variable; copy-pasted multi-output pipeline code where a tag was meant to be a new TupleTag<> but was cloned.","solutions":["Ensure each output in the PCollectionTuple uses a distinct TupleTag — create a new TupleTag for the second output instead of reusing the first.","Review TupleTag equality: two TupleTag instances compare equal when constructed without an id only if same object; with explicit ids, duplicate id strings collide — use unique ids.","If tags come from user config or a collection, validate uniqueness (e.g. by tag id) before building the PCollectionTuple."],"exampleFix":"// before\nTupleTag<String> out = new TupleTag<>(\"out\");\nPCollectionTuple.of(out, mainPc).and(out, sidePc); // throws\n// after\nTupleTag<String> outMain = new TupleTag<>(\"outMain\");\nTupleTag<String> outSide = new TupleTag<>(\"outSide\");\nPCollectionTuple.of(outMain, mainPc).and(outSide, sidePc);","handlingStrategy":"validation","validationCode":"Set<TupleTag<?>> seen = new HashSet<>();\nfor (TupleTag<?> tag : tags) {\n  if (!seen.add(tag)) throw new IllegalArgumentException(\"duplicate TupleTag: \" + tag.getId());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare one final TupleTag per side output in the DoFn, never reuse a tag for two outputs.","Give every TupleTag an explicit unique id string when tags cross serialization boundaries.","Validate tag collections for uniqueness before building PCollectionTuples in generated/config-driven pipelines."],"tags":["java","apache-beam","duplicate-key","illegal-argument"],"backgroundTag":"duplicate-key","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}