{"record":{"id":"f004edab143d6ad8","repo":"apache/beam","slug":"numpartitions-must-be-0","errorCode":null,"errorMessage":"numPartitions must be > 0","messagePattern":"numPartitions must be > 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java","lineNumber":213,"sourceCode":"  private static class PartitionDoFn<X> extends DoFn<X, Void> {\n    private final int numPartitions;\n    private final TupleTagList outputTags;\n    private final Contextful<Contextful.Fn<X, Integer>> ctxFn;\n    private final Object originalFnClassForDisplayData;\n\n    /**\n     * Constructs a PartitionDoFn.\n     *\n     * @throws IllegalArgumentException if {@code numPartitions <= 0}\n     */\n    private PartitionDoFn(\n        int numPartitions,\n        Contextful<Contextful.Fn<X, Integer>> ctxFn,\n        Object originalFnClassForDisplayData) {\n      this.ctxFn = ctxFn;\n      this.originalFnClassForDisplayData = originalFnClassForDisplayData;\n      if (numPartitions <= 0) {\n        throw new IllegalArgumentException(\"numPartitions must be > 0\");\n      }\n\n      this.numPartitions = numPartitions;\n\n      TupleTagList buildOutputTags = TupleTagList.empty();\n      for (int partition = 0; partition < numPartitions; partition++) {\n        buildOutputTags = buildOutputTags.and(new TupleTag<X>());\n      }\n      outputTags = buildOutputTags;\n    }\n\n    public TupleTagList getOutputTags() {\n      return outputTags;\n    }\n\n    @ProcessElement\n    public void processElement(ProcessContext c) throws Exception {\n      X input = c.element();","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java#L195-L231","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure numPartitions is a positive integer before calling Partition.of","Check where the partition count is computed/loaded from config for unset or negative values","Clamp or default the value, e.g. Math.max(1, configuredPartitions)"],"exampleFix":"// before\nint partitions = config.get(\"partitions\"); // 0 when unset\nPCollectionList<T> out = pipeline.apply(Partition.of(partitions, fn));\n// after\nint partitions = Math.max(1, config.get(\"partitions\", 1));\nPCollectionList<T> out = pipeline.apply(Partition.of(partitions, fn));","handlingStrategy":"validation","validationCode":"if (numPartitions <= 0) { throw new IllegalArgumentException(\"numPartitions must be > 0, got \" + numPartitions); }","typeGuard":"boolean isValidPartitionCount(Integer n) { return n != null && n > 0; }","tryCatchPattern":null,"preventionTips":["Validate any config/env-sourced partition counts at pipeline startup","Never pass raw config values without defaults; use Math.max(1, value)","Add unit tests for partition-count computation helpers"],"tags":["java","apache-beam","pipeline-construction","argument-validation"],"backgroundTag":"value-out-of-range","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"}