{"record":{"id":"4c2787b20d63c5fe","repo":"ben-manes/caffeine","slug":"null-map","errorCode":null,"errorMessage":"null map","messagePattern":"null map","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"caffeine/src/main/java/com/github/benmanes/caffeine/cache/LocalAsyncCache.java","lineNumber":693,"sourceCode":"      return resolve(asyncCache().get(key, mappingFunction));\n    }\n\n    @Override\n    public Map<K, V> getAll(\n        Iterable<? extends K> keys,\n        Function<\n            ? super Set<? extends K>,\n            ? extends Map<? extends K, ? extends V>> mappingFunction) {\n      return resolve(asyncCache().getAll(keys, mappingFunction));\n    }\n\n    @SuppressWarnings({\"PMD.AvoidThrowingNullPointerException\",\n      \"PMD.PreserveStackTrace\", \"UnusedException\"})\n    protected static <T> T resolve(CompletableFuture<T> future) {\n      try {\n        return future.join();\n      } catch (NullMapCompletionException e) {\n        throw new NullPointerException(\"null map\");\n      } catch (CompletionException e) {\n        if (e.getCause() instanceof RuntimeException) {\n          throw (RuntimeException) e.getCause();\n        } else if (e.getCause() instanceof Error) {\n          throw (Error) e.getCause();\n        }\n        throw e;\n      }\n    }\n\n    @Override\n    public void put(K key, V value) {\n      requireNonNull(value);\n      asyncCache().cache().put(key, CompletableFuture.completedFuture(value));\n    }\n\n    @Override\n    public void putAll(Map<? extends K, ? extends V> map) {","sourceCodeStart":675,"sourceCodeEnd":711,"githubUrl":"https://github.com/ben-manes/caffeine/blob/9da6581ee366aa63c51e0dc96692d02f9c29ccff/caffeine/src/main/java/com/github/benmanes/caffeine/cache/LocalAsyncCache.java#L675-L711","documentation":"LocalAsyncCache.resolve joins the future returned by an async bulk mapping function; if it completed with a null map (signaled by the internal NullMapCompletionException), resolve converts it into NullPointerException(\"null map\"). Bulk loads must return a map (an empty one if nothing was loaded) — null is a contract violation, matching the Map/ConcurrentMap rule that null collections are forbidden.","triggerScenarios":"cache.getAll(keys, mappingFunction) where mappingFunction's future completes with null; a CacheLoader/AsyncCacheLoader whose loadAll/asyncLoadAll returns null (e.g. from a repository returning null on empty results).","commonSituations":"DAO/repository layers that signal \"not found\" with null instead of an empty map; Optional.map(...) chains that yield null futures; third-party bulk APIs returning null for empty input sets.","solutions":["Return an empty map (or a map covering the requested keys) instead of null from loadAll/asyncLoadAll and from getAll mapping functions","Wrap third-party calls: return result != null ? result : Map.of();","Treat 'no data found' as empty, not null — absent keys are simply missing from the result"],"exampleFix":"// before\nCompletableFuture<Map<K, V>> f = CompletableFuture.completedFuture(repo.findAll(keys)); // null when empty\n\ncache.getAll(keys, f::join... ); // NullPointerException: null map\n\n// after\nvar found = repo.findAll(keys); // may be null\nreturn CompletableFuture.completedFuture(found == null ? Map.<K, V>of() : found);","handlingStrategy":"validation","validationCode":"// Null-safe the mapping result before it reaches getAll:\nstatic <K, V> CompletableFuture<Map<K, V>> nullSafe(CompletableFuture<Map<K, V>> f) {\n  return f.thenApply(m -> (m == null) ? Map.<K, V>of() : m);\n}\ncache.getAll(keys, ks -> nullSafe(bulkLoad(ks)));","typeGuard":null,"tryCatchPattern":"try {\n  return cache.synchronous().getAll(keys);\n} catch (NullPointerException e) {\n  if (\"null map\".equals(e.getMessage())) {\n    // loader returned null: treat as empty and continue\n    return Map.of();\n  }\n  throw e;\n}","preventionTips":["Always return a map from loadAll/asyncLoadAll — empty when nothing matched, never null","Wrap third-party bulk APIs: result != null ? result : Map.of()","Assert non-null bulk results in loader unit tests"],"tags":["caffeine","async","bulk-load","null-map","null-pointer"],"backgroundTag":null,"analyzedSha":"9da6581ee366aa63c51e0dc96692d02f9c29ccff","analyzedAt":"2026-08-14T14:45:28.147Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}