{"record":{"id":"71087125b079b009","repo":"apache/druid","slug":"bitset-cannot-contain-null-values","errorCode":null,"errorMessage":"BitSet cannot contain null values","messagePattern":"BitSet cannot contain null values","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"warning","filePath":"processing/src/main/java/org/apache/druid/collections/IntegerSet.java","lineNumber":90,"sourceCode":"    return new BitSetIterator(mutableBitmap);\n  }\n\n  @Override\n  public Object[] toArray()\n  {\n    Integer[] retval = new Integer[mutableBitmap.size()];\n    int pos = 0;\n    for (Integer i : this) {\n      retval[pos++] = i;\n    }\n    return retval;\n  }\n\n  @Override\n  public boolean add(Integer integer)\n  {\n    if (null == integer) {\n      throw new NullPointerException(\"BitSet cannot contain null values\");\n    }\n    if (integer < 0) {\n      throw new IllegalArgumentException(\"Only positive integers or zero can be added\");\n    }\n    boolean isSet = mutableBitmap.get(integer);\n    mutableBitmap.add(integer.intValue());\n    return !isSet;\n  }\n\n  @Override\n  public boolean remove(Object o)\n  {\n    if (o == null) {\n      throw new NullPointerException(\"BitSet cannot contain null values\");\n    }\n    if (o instanceof Integer) {\n      Integer integer = (Integer) o;\n      boolean isSet = mutableBitmap.get(integer);","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/collections/IntegerSet.java#L72-L108","documentation":"IntegerSet.add rejects null elements: the underlying mutable bitmap (Roaring/concise-style) stores primitive ints and cannot represent a null Integer, so a NPE is thrown as an explicit contract enforcement rather than failing later with an opaque NPE.","triggerScenarios":"Adding a null Integer via add() or addAll() (which iterates add()), including automated tests testSimpleAdd/testIsEmpty/testIntOverflow that cover this path.","commonSituations":"Collecting integers from a data source that can yield nulls (nullable columns, absent lookups) and inserting them directly into an IntegerSet.","solutions":["Filter nulls before adding to the IntegerSet.","Fix the caller that supplies boxed Integer values from a collection that may contain nulls.","Use a structure that supports nulls if null representation is genuinely required."],"exampleFix":"// before\nset.add(maybeNull);\n// after\nif (maybeNull != null) { set.add(maybeNull); }","handlingStrategy":"validation","validationCode":"// filter before addAll\nList<Integer> safe = input.stream().filter(Objects::nonNull).collect(Collectors.toList());\nset.addAll(safe);","typeGuard":"boolean isSafeForBitSet(Integer i) { return i != null && i >= 0; }","tryCatchPattern":"try {\n  set.add(i);\n} catch (NullPointerException e) {\n  // null value supplied; skip or substitute default\n}","preventionTips":["Filter nulls before building IntegerSet","Reject negative values early","Choose a nullable-tolerant collection if nulls are meaningful"],"tags":["collections","null-check","bitset"],"backgroundTag":"null-argument","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}