{"record":{"id":"ad12f31ec08d878c","repo":"apache/beam","slug":"smallbatchtag-and-largebatchtag-must-be-different","errorCode":null,"errorMessage":"smallBatchTag and largeBatchTag must be different","messagePattern":"smallBatchTag and largeBatchTag must be different","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/BundleLifter.java","lineNumber":136,"sourceCode":"        taggedOutput.output(element);\n      }\n    }\n  }\n\n  private BundleLifter(TupleTag<T> smallBatchTag, TupleTag<T> largeBatchTag, int threshold) {\n    this(smallBatchTag, largeBatchTag, threshold, x -> 1);\n  }\n\n  private BundleLifter(\n      TupleTag<T> smallBatchTag,\n      TupleTag<T> largeBatchTag,\n      int threshold,\n      SerializableFunction<T, Integer> elementSizer) {\n    if (smallBatchTag == null || largeBatchTag == null) {\n      throw new IllegalArgumentException(\"smallBatchTag and largeBatchTag must not be null\");\n    }\n    if (smallBatchTag.getId().equals(largeBatchTag.getId())) {\n      throw new IllegalArgumentException(\"smallBatchTag and largeBatchTag must be different\");\n    }\n    if (threshold <= 0) {\n      throw new IllegalArgumentException(\"Threshold must be a positive integer\");\n    }\n\n    this.smallBatchTag = smallBatchTag;\n    this.largeBatchTag = largeBatchTag;\n    this.threshold = threshold;\n    this.elementSizer = elementSizer;\n  }\n\n  public static <T> BundleLifter<T> of(\n      TupleTag<T> smallBatchTag, TupleTag<T> largeBatchTag, int threshold) {\n    return new BundleLifter<>(smallBatchTag, largeBatchTag, threshold);\n  }\n\n  public static <T> BundleLifter<T> of(\n      TupleTag<T> smallBatchTag,","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/BundleLifter.java#L118-L154","documentation":"BundleLifter's constructor validates that the two state tags used to distinguish small and large batches refer to different state IDs. If both tags share the same ID, small and large batch state would collide in the batched state map, so the library refuses to construct the lifter.","triggerScenarios":"Calling new BundleLifter<>(typeDescriptor, batcherClass, batcherSupplier, smallBatchTag, largeBatchTag, threshold, elementSizer) where smallBatchTag.getId().equals(largeBatchTag.getId()) — typically because the same StateTag (or two tags built with identical parameters, since getId() derives from them) was passed for both parameters.","commonSituations":"Copy-pasting a single StateTag definition and reusing it for both parameters; constructing two tags from the same template with identical inputs and assuming they are distinct; refactoring that accidentally collapsed two tag constants into one.","solutions":["Create two distinct StateTag instances with different identities/parameters for small and large batch tags.","If the tags are built programmatically, make their getId() inputs differ (e.g., different names or components).","Log both tag IDs before constructing BundleLifter to verify they differ."],"exampleFix":"// before\nStateTag<Object, List<T>> batchTag = StateTags.key(\"batch\");\nBundleLifter<T> lifter = new BundleLifter<>(td, cls, supplier, batchTag, batchTag, 100, sizer);\n// after\nStateTag<Object, List<T>> smallBatchTag = StateTags.key(\"small-batch\");\nStateTag<Object, List<T>> largeBatchTag = StateTags.key(\"large-batch\");\nBundleLifter<T> lifter = new BundleLifter<>(td, cls, supplier, smallBatchTag, largeBatchTag, 100, sizer);","handlingStrategy":"validation","validationCode":"if (smallBatchTag == null || largeBatchTag == null) throw new IllegalArgumentException(\"tags must not be null\");\ncheckState(!smallBatchTag.getId().equals(largeBatchTag.getId()), \"smallBatchTag and largeBatchTag must differ\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Define small and large batch tags as separate static final constants with clearly different names.","Never reuse a single StateTag variable for both constructor parameters."],"tags":["java","constructor-validation","apache-beam","iceberg"],"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"}