{"record":{"id":"135eb1e3698a684f","repo":"apache/druid","slug":"at-least-2-bins-expected","errorCode":null,"errorMessage":"at least 2 bins expected","messagePattern":"at least 2 bins expected","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":500,"severity":"error","filePath":"extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregator.java","lineNumber":73,"sourceCode":"      @JsonProperty(\"numBins\") @Nullable final Integer numBins)\n  {\n    this.name = Preconditions.checkNotNull(name, \"name is null\");\n    this.field = Preconditions.checkNotNull(field, \"field is null\");\n    this.splitPoints = splitPoints;\n    this.numBins = numBins;\n    if (splitPoints != null && numBins != null) {\n      throw new IAE(\"Cannot accept both 'splitPoints' and 'numBins'\");\n    }\n  }\n\n  @Override\n  public Object compute(final Map<String, Object> combinedAggregators)\n  {\n    final KllDoublesSketch sketch = (KllDoublesSketch) field.compute(combinedAggregators);\n    final int numBins = this.splitPoints != null ? this.splitPoints.length + 1 :\n        (this.numBins != null ? this.numBins.intValue() : DEFAULT_NUM_BINS);\n    if (numBins < 2) {\n      throw new IAE(\"at least 2 bins expected\");\n    }\n    if (sketch.isEmpty()) {\n      final double[] histogram = new double[numBins];\n      Arrays.fill(histogram, Double.NaN);\n      return histogram;\n    }\n    final double[] splitPoints;\n    if (this.splitPoints != null) {\n      splitPoints = this.splitPoints;\n    } else {\n      final double min = sketch.getMinItem();\n      final double max = sketch.getMaxItem();\n      if (min == max) {\n        // if min is equal to max, we can't create an array of equally spaced points.\n        // all values would go into the first bucket anyway, and the remaining\n        // buckets are left as zero.\n        final double[] histogram = new double[numBins];\n        histogram[0] = sketch.getN();","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregator.java#L55-L91","documentation":"KllDoublesSketchToHistogramPostAggregator.compute derives the bin count from splitPoints (length+1), numBins, or the default, and throws IllegalArgumentException when fewer than 2 bins result. A histogram needs at least two edges/bins to be meaningful. The check also fires when a single split point (1 split => 2 bins is fine) yields an invalid count or numBins < 2 was requested.","triggerScenarios":"Setting numBins to 0 or 1; supplying an empty splitPoints array (length 0 => 1 bin); passing null/empty splitPoints with a numBins below 2 in compute.","commonSituations":"Misconfigured spec with numBins: 1 or empty splitPoints: []; a dynamic spec generator producing empty arrays; users thinking splitPoints means edge count including outer bounds.","solutions":["Set numBins to at least 2","Provide at least 1 split point (giving 2 bins) if using splitPoints","Use an empty/null config to fall back to DEFAULT_NUM_BINS instead of forcing a tiny bin count"],"exampleFix":"// before\n{\"type\":\"kllDoublesSketchToHistogram\",\"name\":\"h\",\"field\":f,\"numBins\":1}\n// after\n{\"type\":\"kllDoublesSketchToHistogram\",\"name\":\"h\",\"field\":f,\"numBins\":10}","handlingStrategy":"validation","validationCode":"int bins = splitPoints != null ? splitPoints.length + 1 : (numBins != null ? numBins : 20);\nif (bins < 2) throw new IllegalArgumentException(\"numBins/splitPoints must yield at least 2 bins\");","typeGuard":null,"tryCatchPattern":"try { result = postAgg.compute(combined); } catch (IllegalArgumentException e) { log.error(\"Invalid histogram config: {}\", e.getMessage()); }","preventionTips":["Always set numBins >= 2 or supply at least one split point","Guard dynamic spec generators against empty splitPoints arrays","Remember splitPoints.length must be >= 1"],"tags":["druid","datasketches","kll","post-aggregator","validation"],"backgroundTag":"invalid-argument-value","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"}