{"record":{"id":"debc01b7ea9c9bcf","repo":"apache/beam","slug":"partition-function-returned-out-of-bounds-index","errorCode":null,"errorMessage":"Partition function returned out of bounds index: ","messagePattern":"Partition function returned out of bounds index: ","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java","lineNumber":238,"sourceCode":"        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();\n      int partition = ctxFn.getClosure().apply(input, Contextful.Fn.Context.wrapProcessContext(c));\n      if (0 <= partition && partition < numPartitions) {\n        @SuppressWarnings(\"unchecked\")\n        TupleTag<X> typedTag = (TupleTag<X>) outputTags.get(partition);\n        c.output(typedTag, input);\n      } else {\n        throw new IndexOutOfBoundsException(\n            \"Partition function returned out of bounds index: \"\n                + partition\n                + \" not in [0..\"\n                + numPartitions\n                + \")\");\n      }\n    }\n\n    @Override\n    public void populateDisplayData(DisplayData.Builder builder) {\n      super.populateDisplayData(builder);\n      builder\n          .add(DisplayData.item(\"numPartitions\", numPartitions).withLabel(\"Partition Count\"))\n          .add(\n              DisplayData.item(\"partitionFn\", originalFnClassForDisplayData.getClass())\n                  .withLabel(\"Partition Function\"));\n    }\n","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Partition.java#L220-L256","documentation":"During DoFn.processElement, Beam invokes the user-provided partition function to decide which output tag an element goes to. If the returned index is negative or >= numPartitions, no matching output exists, so Beam throws IndexOutOfBoundsException naming the invalid index and valid range.","triggerScenarios":"A partition function (e.g. fn -> element.length() % 0, integer division modulo with 0, or a function returning indices based on a dataset value exceeding the declared partition count, or returning -1 as a sentinel) produces an index outside [0, numPartitions).","commonSituations":"Partition function logic changed after partition count was fixed; using % with zero; sentinel values like -1 for 'drop' elements; mismatch between number of outputs declared and indices the function can return.","solutions":["Fix the partition function to always return an index in [0, numPartitions)","Clamp the index inside the function, e.g. Math.floorMod(key, numPartitions)","If elements should be filtered out, filter them before Partition instead of returning a sentinel index"],"exampleFix":"// before\nreturn element.length() == 0 ? -1 : element.length() % numPartitions;\n// after\nif (element.isEmpty()) return 0; // or filter empties beforehand\nreturn Math.floorMod(element.length(), numPartitions);","handlingStrategy":"validation","validationCode":"int idx = partitionFn.apply(element);\nif (idx < 0 || idx >= numPartitions) throw new IllegalArgumentException(\"partition fn returned \" + idx);","typeGuard":null,"tryCatchPattern":"try { input.apply(Partition.of(n, fn)); } catch (IndexOutOfBoundsException e) { LOG.error(\"partition function returned bad index\", e); throw new IllegalArgumentException(\"Fix partition fn\", e); }","preventionTips":["Use Math.floorMod for modulo-based partitioning to avoid negatives","Filter out undesired elements before Partition rather than returning sentinel indices","Keep the partition function's output range coupled to numPartitions in one place"],"tags":["java","apache-beam","runtime","index-out-of-range"],"backgroundTag":"index-out-of-bounds","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"}