{"record":{"id":"796bc232655d39f9","repo":"apache/druid","slug":"max-level-found-in-leveltototalbatches-is-d-0-in","errorCode":null,"errorMessage":"Max level found in levelToTotalBatches is %d (0-indexed). Cannot set totalMergingLevels to %d","messagePattern":"Max level found in levelToTotalBatches is (.+?) \\(0-indexed\\)\\. Cannot set totalMergingLevels to (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/frame/processor/SuperSorterProgressTracker.java","lineNumber":104,"sourceCode":"   * Set total merging levels for the SuperSorter it is tracking. Can be set only once\n   */\n  public synchronized void setTotalMergingLevels(final int totalMergingLevels)\n  {\n    if (this.totalMergingLevels != SuperSorter.UNKNOWN_LEVEL) {\n      throw new ISE(\"Total merging levels already defined for the merge sort.\");\n    }\n    levelToMergedBatches.keySet().stream().max(Ordering.natural()).ifPresent(max -> {\n      if (max >= totalMergingLevels) {\n        throw new ISE(\n            \"Max level found in levelToMergedBatches is %d (0-indexed). Cannot set totalMergingLevels to %d\",\n            max,\n            totalMergingLevels\n        );\n      }\n    });\n    levelToTotalBatches.keySet().stream().max(Ordering.natural()).ifPresent(max -> {\n      if (max >= totalMergingLevels) {\n        throw new ISE(\n            \"Max level found in levelToTotalBatches is %d (0-indexed). Cannot set totalMergingLevels to %d\",\n            max,\n            totalMergingLevels\n        );\n      }\n    });\n\n    this.totalMergingLevels = totalMergingLevels;\n  }\n\n  /**\n   * Sets the total mergers for a level. Can be set only once, except for the ultimate level (if total levels are known)\n   * because they get overridden by totalMergersForUltimateLevel\n   */\n  public synchronized void setTotalMergersForLevel(final int level, final long totalMergers)\n  {\n    if (level < 0) {\n      throw new ISE(\"Unable to set %d total mergers for level %d. Level must be non-negative\", totalMergers, level);","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/frame/processor/SuperSorterProgressTracker.java#L86-L122","documentation":"Same validation as the levelToMergedBatches check, but for levelToTotalBatches: if the tracker's recorded total-batch levels already reach or exceed the proposed totalMergingLevels, setTotalMergingLevels throws. This guarantees the write-once level count stays consistent with all existing per-level batch totals (0-indexed levels).","triggerScenarios":"setTotalMergersForLevel was called (populating levelToTotalBatches) for a level at or above the value later passed to setTotalMergingLevels — i.e., level totals were registered before the level count was finalized.","commonSituations":"See trigger scenarios.","solutions":["Call setTotalMergingLevels before any setTotalMergersForLevel calls so levelToTotalBatches is empty when levels are set.","Recompute totalMergingLevels to cover every level for which mergers were already registered.","Replace the tracker with a new instance if the level structure of the sort has changed mid-run.","Add an assertion in test code that totalMergingLevels is set first, to catch ordering regressions early."],"exampleFix":"// before\ntracker.setTotalMergersForLevel(2, 4);\ntracker.setTotalMergingLevels(2); // valid levels 0..1 -> throws\n// after\ntracker.setTotalMergingLevels(3); // covers levels 0..2\ntracker.setTotalMergersForLevel(2, 4);","handlingStrategy":"validation","validationCode":"assert tracker.getLevelToTotalBatches().keySet().stream().max(Integer::compare).orElse(-1) < levels\n    : \"existing level totals exceed new totalMergingLevels\";","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call setTotalMergingLevels before setTotalMergersForLevel.","Ensure the level count covers every level the scheduler registers.","Use a new tracker instance when the sort's level structure changes."],"tags":["internal-state","initialization-order","sorting"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}