{"record":{"id":"1c4e26ac54ad7ffc","repo":"TheAlgorithms/Java","slug":"key-and-value-must-not-be-null","errorCode":null,"errorMessage":"Key and value must not be null","messagePattern":"Key and value must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java","lineNumber":166,"sourceCode":"        put(key, value, defaultTTL);\n    }\n\n    /**\n     * Adds a key-value pair to the cache with a specified time-to-live (TTL).\n     *\n     * <p>If the key already exists, its value is removed, re-inserted at tail and its TTL is reset.\n     * If the key does not exist and the cache is full, the oldest entry is evicted to make space.\n     * Expired entries are also cleaned up prior to any eviction. The eviction listener\n     * is notified when an entry gets evicted.\n     *\n     * @param key        the key to associate with the cached value; must not be {@code null}\n     * @param value      the value to be cached; must not be {@code null}\n     * @param ttlMillis  the time-to-live for this entry in milliseconds; must be >= 0\n     * @throws IllegalArgumentException if {@code key} or {@code value} is {@code null}, or if {@code ttlMillis} is negative\n     */\n    public void put(K key, V value, long ttlMillis) {\n        if (key == null || value == null) {\n            throw new IllegalArgumentException(\"Key and value must not be null\");\n        }\n        if (ttlMillis < 0) {\n            throw new IllegalArgumentException(\"TTL must be >= 0\");\n        }\n\n        lock.lock();\n        try {\n            // If key already exists, remove it\n            CacheEntry<V> oldEntry = cache.remove(key);\n            if (oldEntry != null && !oldEntry.isExpired()) {\n                notifyEviction(key, oldEntry.value);\n            }\n\n            // Evict expired entries to make space for new entry\n            evictExpired();\n\n            // If no expired entry was removed, remove the oldest\n            if (cache.size() >= capacity) {","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java#L148-L184","documentation":"Thrown by FIFOCache.put(K, V, long) when either the key or the value is null. The cache stores entries in a HashMap and notifies an eviction listener on overwrite, so a null value would be ambiguous with an absent/expired entry. The check fires before lock acquisition and before any TTL validation.","triggerScenarios":"cache.put(key, null, ttl); cache.put(null, value, ttl); inserting the result of a computation that legitimately returned null; deserialized DTOs whose optional fields default to null.","commonSituations":"Caching the result of a repository lookup that can legitimately be absent; test fixtures that forget to set a field; ORM mappings that yield null for unset columns.","solutions":["Skip caching when the computed value is null: if (value != null) cache.put(key, value, ttl);","Represent 'absent' with a sentinel/Optional rather than null.","Validate both key and value at the service boundary."],"exampleFix":"// before\ncache.put(id, repo.find(id), ttl);\n// after\nV value = repo.find(id);\nif (id != null && value != null) cache.put(id, value, ttl);","handlingStrategy":"validation","validationCode":"if (key == null || value == null) {\n    // do not cache; log if unexpected\n    return;\n}\ncache.put(key, value, ttlMillis);","typeGuard":"static <K, V> boolean isCacheable(K key, V value) {\n    return key != null && value != null;\n}","tryCatchPattern":null,"preventionTips":["Do not cache repository results that can legitimately be absent; treat null as 'do not cache'.","Use a sentinel or Optional to represent absence.","Validate both key and value at the service boundary."],"tags":["java","fifo-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"}