{"record":{"id":"d2a82f4376dcdeca","repo":"apache/hadoop","slug":"key-may-not-be-null","errorCode":null,"errorMessage":"Key may not be null","messagePattern":"Key may not be null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/bloom/CountingBloomFilter.java","lineNumber":137,"sourceCode":"      long bucketValue = (buckets[wordNum] & bucketMask) >>> bucketShift;\n      \n      // only increment if the count in the bucket is less than BUCKET_MAX_VALUE\n      if(bucketValue < BUCKET_MAX_VALUE) {\n        // increment by 1\n        buckets[wordNum] = (buckets[wordNum] & ~bucketMask) | ((bucketValue + 1) << bucketShift);\n      }\n    }\n  }\n\n  /**\n   * Removes a specified key from <i>this</i> counting Bloom filter.\n   * <p>\n   * <b>Invariant</b>: nothing happens if the specified key does not belong to <i>this</i> counter Bloom filter.\n   * @param key The key to remove.\n   */\n  public void delete(Key key) {\n    if(key == null) {\n      throw new NullPointerException(\"Key may not be null\");\n    }\n    if(!membershipTest(key)) {\n      throw new IllegalArgumentException(\"Key is not a member\");\n    }\n\n    int[] h = hash.hash(key);\n    hash.clear();\n\n    for(int i = 0; i < nbHash; i++) {\n      // find the bucket\n      int wordNum = h[i] >> 4;          // div 16\n      int bucketShift = (h[i] & 0x0f) << 2;  // (mod 16) * 4\n      \n      long bucketMask = 15L << bucketShift;\n      long bucketValue = (buckets[wordNum] & bucketMask) >>> bucketShift;\n      \n      // only decrement if the count in the bucket is between 0 and BUCKET_MAX_VALUE\n      if(bucketValue >= 1 && bucketValue < BUCKET_MAX_VALUE) {","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/bloom/CountingBloomFilter.java#L119-L155","documentation":"CountingBloomFilter.delete(Key) removes a key by decrementing the counters it previously incremented; it first requires a non-null key and throws NullPointerException('Key may not be null') as an explicit guard. This mirrors add() and membershipTest() in the same class, failing fast with a readable message instead of an opaque NPE from the hashing layer.","triggerScenarios":"cbf.delete(null); deleting keys from a nullable lookup result; maintenance jobs sweeping collections that contain null entries.","commonSituations":"Expiry/removal passes over caches where some entries were never populated; the null key arriving from deserialization or a cleared map slot.","solutions":["Null-check before calling delete() and skip null entries.","Filter nulls out of the deletion candidate list before the loop.","Fix the upstream nullable source of Keys."],"exampleFix":"// before\nfor (Key k : expiredKeys) {\n  cbf.delete(k); // list contained a null\n}\n// throws NullPointerException: Key may not be null\n\n// after\nfor (Key k : expiredKeys) {\n  if (k != null) {\n    cbf.delete(k);\n  }\n}","handlingStrategy":"validation","validationCode":"for (Key k : expiredKeys) {\n  if (k != null) {\n    cbf.delete(k);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter nulls from deletion candidate lists before the loop.","Keep removal queues typed and non-null by construction.","Log skipped nulls during maintenance sweeps for auditability."],"tags":["bloom-filter","counting-bloom-filter","null-check","precondition","hadoop-common"],"backgroundTag":"null-argument","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}