{"record":{"id":"caaf4ef3efb8d86a","repo":"TheAlgorithms/Java","slug":"key-must-not-be-null-caaf4e","errorCode":null,"errorMessage":"Key must not be null","messagePattern":"Key must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/datastructures/caches/LIFOCache.java","lineNumber":120,"sourceCode":"        this.evictionListener = builder.evictionListener;\n        this.evictionStrategy = builder.evictionStrategy;\n    }\n\n    /**\n     * Retrieves the value associated with the specified key from the cache.\n     *\n     * <p>If the key is not present or the corresponding entry has expired, this method\n     * returns {@code null}. If an expired entry is found, it will be removed and the\n     * eviction listener (if any) will be notified. Cache hit-and-miss statistics are\n     * also updated accordingly.\n     *\n     * @param key the key whose associated value is to be returned; must not be {@code null}\n     * @return the cached value associated with the key, or {@code null} if not present or expired\n     * @throws IllegalArgumentException if {@code key} is {@code null}\n     */\n    public V get(K key) {\n        if (key == null) {\n            throw new IllegalArgumentException(\"Key must not be null\");\n        }\n\n        lock.lock();\n        try {\n            evictionStrategy.onAccess(this);\n\n            final CacheEntry<V> entry = cache.get(key);\n            if (entry == null || entry.isExpired()) {\n                if (entry != null) {\n                    cache.remove(key);\n                    keys.remove(key);\n                    notifyEviction(key, entry.value);\n                }\n                misses++;\n                return null;\n            }\n            hits++;\n            return entry.value;","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/datastructures/caches/LIFOCache.java#L102-L138","documentation":"Thrown by LIFOCache.get(K) when the key is null. The cache is HashMap-backed and null keys would collide with the absent-entry contract; the guard runs before lock acquisition and before any eviction-strategy or statistics updates. LIFOCache is the LIFO (stack-based) sibling of FIFOCache and shares the same null-key policy.","triggerScenarios":"cache.get(null); cache.get(map.get(absentKey)) yielding null; lookups driven by unvalidated user input.","commonSituations":"Request parameters mapped straight to cache keys; optional deserialized fields; migrating from a tolerant cache implementation.","solutions":["Null-check the key before lookup, returning a default upstream.","Use Optional.ofNullable(key).map(cache::get).orElse(null).","Validate at the service boundary."],"exampleFix":"// before\nV v = cache.get(request.getKey());\n// after\nK k = request.getKey();\nif (k == null) return defaultValue;\nreturn cache.get(k);","handlingStrategy":"validation","validationCode":"if (key == null) return defaultValue;\nV value = cache.get(key);","typeGuard":"static <K> boolean isLookupKey(K key) {\n    return key != null;\n}","tryCatchPattern":null,"preventionTips":["Validate request parameters at the controller before they reach the cache.","Centralize lookups in a helper returning Optional.","Never pipe Map.get() output straight into cache.get()."],"tags":["java","lifo-cache","null-check","argument-validation","cache"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}