{"record":{"id":"fa488fad809adeb7","repo":"apache/beam","slug":"smallbatchtag-and-largebatchtag-must-not-be-null","errorCode":null,"errorMessage":"smallBatchTag and largeBatchTag must not be null","messagePattern":"smallBatchTag and largeBatchTag must not be null","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":133,"sourceCode":"      OutputReceiver<T> taggedOutput = receiver.get(targetTag);\n\n      for (T element : buffer) {\n        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  }","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/BundleLifter.java#L115-L151","documentation":"BundleLifter's private constructor validates its inputs: the smallBatchTag and largeBatchTag TupleTags must be non-null (and distinct). A null tag would make the downstream partition/union operation unable to route elements, so it fails fast with IllegalArgumentException.","triggerScenarios":"Programmatically constructing a BundleLifter (e.g. builder or internal expansion of a batching transform) while passing null for either TupleTag.","commonSituations":"Custom Beam pipeline code reusing BundleLifter for bespoke batching; refactors where tags were conditionally omitted; misconfigured PTransform builders that skip tag initialization.","solutions":["Provide distinct, non-null TupleTag instances for both small and large batches","Initialize the tags in the transform's builder/constructor before expansion","Assert tag non-nullness earlier (at builder build() time) for clearer errors","Ensure the two tags have different ids"],"exampleFix":"// before\nnew BundleLifter<>(null, largeTag, threshold, sizer);\n// after\nnew BundleLifter<>(TupleTag[\"small\"], TupleTag[\"large\"], threshold, sizer);","handlingStrategy":"type-guard","validationCode":"Objects.requireNonNull(smallBatchTag, \"smallBatchTag\"); Objects.requireNonNull(largeBatchTag, \"largeBatchTag\");","typeGuard":"boolean validTags(TupleTag<?> a, TupleTag<?> b){ return a!=null && b!=null && !a.getId().equals(b.getId()); }","tryCatchPattern":"try { lifter = newBundleLifter(small, large, threshold, sizer); } catch (IllegalArgumentException e) { throw new PipelineSetupException(e); }","preventionTips":["Initialize TupleTags as static final constants","Validate tags at transform build time","Ensure unique tag ids","Add unit tests for transform expansion"],"tags":["java","iceberg","beam","argument-validation"],"backgroundTag":"null-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"}