{"record":{"id":"5314a6178ac842ed","repo":"TheAlgorithms/Java","slug":"ttl-must-be-0","errorCode":null,"errorMessage":"TTL must be >= 0","messagePattern":"TTL must be >= 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java","lineNumber":169,"sourceCode":"    /**\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) {\n                Iterator<Map.Entry<K, CacheEntry<V>>> it = cache.entrySet().iterator();\n                if (it.hasNext()) {\n                    Map.Entry<K, CacheEntry<V>> eldest = it.next();","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java#L151-L187","documentation":"Thrown by FIFOCache.put(K, V, long ttlMillis) when ttlMillis is negative. The cache stores an absolute expiry timestamp computed as now + ttlMillis; a negative TTL would set expiry in the past, making the entry instantly invalid and wasting an eviction cycle. The check runs after the null-key/value guard but before lock acquisition.","triggerScenarios":"cache.put(k, v, -1); passing a Duration.toMillis() of a negative Duration; computing TTL from a clock skew where end - start goes negative; config typo supplying a negative number.","commonSituations":"TTL derived from request headers with bad client clocks; environment config (e.g. -Dcache.ttl=-5000) typoed with a leading minus; reusing a duration variable that was inverted elsewhere.","solutions":["Clamp or validate the TTL before calling put: long ttl = Math.max(0, ttlMillis);","Treat negative TTL as 'no expiry' or 'do not cache' per your domain policy, explicitly.","Validate config values at startup and fail fast with a clear message."],"exampleFix":"// before\ncache.put(k, v, duration.toMillis());\n// after\nlong ttl = duration.toMillis();\nif (ttl < 0) throw new IllegalStateException(\"negative ttl from \" + duration);\ncache.put(k, v, ttl);","handlingStrategy":"validation","validationCode":"long ttl = Math.max(0, ttlMillis);\ncache.put(key, value, ttl);","typeGuard":"static boolean isValidTtl(long ttlMillis) {\n    return ttlMillis >= 0;\n}","tryCatchPattern":null,"preventionTips":["Validate all TTL config keys at startup and fail fast.","When deriving TTL from a Duration, assert the Duration is non-negative.","Beware clock-skew arithmetic that can invert end - start."],"tags":["java","fifo-cache","ttl","argument-validation","cache"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}