apache/beam · error · IllegalArgumentException

numPartitions must be > 0

Error message

numPartitions must be > 0

What it means

Beam's Partition transform is constructed with a fixed number of output partitions. The PartitionDoFn constructor validates numPartitions eagerly and throws IllegalArgumentException if it is <= 0, since zero or negative partitions cannot be represented as output TupleTags. This fails fast at pipeline construction rather than at runtime.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java:213

  private static class PartitionDoFn<X> extends DoFn<X, Void> {
    private final int numPartitions;
    private final TupleTagList outputTags;
    private final Contextful<Contextful.Fn<X, Integer>> ctxFn;
    private final Object originalFnClassForDisplayData;

    /**
     * Constructs a PartitionDoFn.
     *
     * @throws IllegalArgumentException if {@code numPartitions <= 0}
     */
    private PartitionDoFn(
        int numPartitions,
        Contextful<Contextful.Fn<X, Integer>> ctxFn,
        Object originalFnClassForDisplayData) {
      this.ctxFn = ctxFn;
      this.originalFnClassForDisplayData = originalFnClassForDisplayData;
      if (numPartitions <= 0) {
        throw new IllegalArgumentException("numPartitions must be > 0");
      }

      this.numPartitions = numPartitions;

      TupleTagList buildOutputTags = TupleTagList.empty();
      for (int partition = 0; partition < numPartitions; partition++) {
        buildOutputTags = buildOutputTags.and(new TupleTag<X>());
      }
      outputTags = buildOutputTags;
    }

    public TupleTagList getOutputTags() {
      return outputTags;
    }

    @ProcessElement
    public void processElement(ProcessContext c) throws Exception {
      X input = c.element();

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure numPartitions is a positive integer before calling Partition.of
  2. Check where the partition count is computed/loaded from config for unset or negative values
  3. Clamp or default the value, e.g. Math.max(1, configuredPartitions)

Example fix

// before
int partitions = config.get("partitions"); // 0 when unset
PCollectionList<T> out = pipeline.apply(Partition.of(partitions, fn));
// after
int partitions = Math.max(1, config.get("partitions", 1));
PCollectionList<T> out = pipeline.apply(Partition.of(partitions, fn));
Defensive patterns

Strategy: validation

Validate before calling

if (numPartitions <= 0) { throw new IllegalArgumentException("numPartitions must be > 0, got " + numPartitions); }

Type guard

boolean isValidPartitionCount(Integer n) { return n != null && n > 0; }

Prevention

When it happens

Trigger: Calling Partition.of(numPartitions, fn) or new Partition<>(numPartitions, ctxFn, ...) with numPartitions = 0 or negative, often when the partition count comes from a computed variable or config that defaults to 0.

Common situations: Reading partition count from config/environment where the value is unset (0); passing an empty list size; off-by-one in dynamic partition count computation.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/f004edab143d6ad8. Report an issue: GitHub.