{"record":{"id":"5706b23f3d8c1a38","repo":"apache/druid","slug":"a-not-b-requires-at-least-1-sketch-5706b2","errorCode":null,"errorMessage":"A-Not-B requires at least 1 sketch","messagePattern":"A-Not-B requires at least 1 sketch","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/tuple/ArrayOfDoublesSketchOperations.java","lineNumber":71,"sourceCode":"    },\n    INTERSECT {\n      @Override\n      public ArrayOfDoublesSketch apply(final int nominalEntries, final int numberOfValues, final ArrayOfDoublesSketch[] sketches)\n      {\n        final ArrayOfDoublesIntersection intersection = new ArrayOfDoublesSetOperationBuilder()\n            .setNominalEntries(nominalEntries).setNumberOfValues(numberOfValues).buildIntersection();\n        for (final ArrayOfDoublesSketch sketch : sketches) {\n          intersection.intersect(sketch, COMBINER);\n        }\n        return intersection.getResult();\n      }\n    },\n    NOT {\n      @Override\n      public ArrayOfDoublesSketch apply(final int nominalEntries, final int numberOfValues, final ArrayOfDoublesSketch[] sketches)\n      {\n        if (sketches.length < 1) {\n          throw new IAE(\"A-Not-B requires at least 1 sketch\");\n        }\n\n        if (sketches.length == 1) {\n          return sketches[0];\n        }\n\n        ArrayOfDoublesSketch result = sketches[0];\n        for (int i = 1; i < sketches.length; i++) {\n          final ArrayOfDoublesAnotB aNotB = new ArrayOfDoublesSetOperationBuilder().setNumberOfValues(numberOfValues)\n              .buildAnotB();\n          aNotB.update(result, sketches[i]);\n          result = aNotB.getResult();\n        }\n        return result;\n      }\n    };\n\n    public abstract ArrayOfDoublesSketch apply(int nominalEntries, int numberOfValues, ArrayOfDoublesSketch[] sketches);","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/tuple/ArrayOfDoublesSketchOperations.java#L53-L89","documentation":"The NOT (A-Not-B) set operation of ArrayOfDoublesSketchOperations requires at least one input sketch to compute a difference. The apply() method validates this and throws IllegalArgumentException when sketches.length < 1, since A-Not-B cannot be evaluated with no sketches.","triggerScenarios":"Invoking ArrayOfDoublesSketchOperations.Operation.NOT.apply() with an empty sketches array, typically from ArrayOfDoublesSketchSetOpPostAggregator when its input fields produce no sketches.","commonSituations":"A post-aggregator whose field expression filters out all rows and yields no sketches; misconfigured query with an empty or all-null field list that survives the fields>1 constructor check but produces nothing at runtime.","solutions":["Ensure the post-aggregator fields actually produce sketches for the queried data","Check query filters/intervals are not excluding all rows feeding the aggregation","Guard the operation site with a length check before calling apply"],"exampleFix":"// before\nArrayOfDoublesSketch result = Operation.NOT.apply(nominalEntries, numValues, sketches);\n// after\nif (sketches.length == 0) {\n  return null; // or an empty sketch\n}\nArrayOfDoublesSketch result = Operation.NOT.apply(nominalEntries, numValues, sketches);","handlingStrategy":"validation","validationCode":"if (sketches == null || sketches.length < 1) {\n  throw new IllegalArgumentException(\"NOT operation requires at least 1 sketch\");\n}","typeGuard":"boolean hasSketches = sketches != null && sketches.length >= 1;","tryCatchPattern":"try {\n  result = Operation.NOT.apply(nominalEntries, numValues, sketches);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"requires at least 1 sketch\")) {\n    result = null; // or empty sketch\n  } else {\n    throw e;\n  }\n}","preventionTips":["Validate that post-aggregator fields produce sketches at runtime","Check query filters do not exclude all input rows","Prefer deserializeSafe()/null-safe field evaluation upstream"],"tags":["druid","datasketches","illegal-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}