{"record":{"id":"921d8b1155b22233","repo":"Blankj/AndroidUtilCode","slug":"the-duration-is-less-than-0","errorCode":null,"errorMessage":"The duration is less than 0.","messagePattern":"The duration is less than 0\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/utilcode/src/main/java/com/blankj/utilcode/util/DebouncingUtils.java","lineNumber":64,"sourceCode":"     * @return {@code true}: yes<br>{@code false}: no\n     */\n    public static boolean isValid(@NonNull final View view, final long duration) {\n        return isValid(String.valueOf(view.hashCode()), duration);\n    }\n\n    /**\n     * Return whether the key is not in a jitter state.\n     *\n     * @param key      The key.\n     * @param duration The duration.\n     * @return {@code true}: yes<br>{@code false}: no\n     */\n    public static boolean isValid(@NonNull String key, final long duration) {\n        if (TextUtils.isEmpty(key)) {\n            throw new IllegalArgumentException(\"The key is null.\");\n        }\n        if (duration < 0) {\n            throw new IllegalArgumentException(\"The duration is less than 0.\");\n        }\n        long curTime = SystemClock.elapsedRealtime();\n        clearIfNecessary(curTime);\n        Long validTime = KEY_MILLIS_MAP.get(key);\n        if (validTime == null || curTime >= validTime) {\n            KEY_MILLIS_MAP.put(key, curTime + duration);\n            return true;\n        }\n        return false;\n    }\n\n    private static void clearIfNecessary(long curTime) {\n        if (KEY_MILLIS_MAP.size() < CACHE_SIZE) return;\n        for (Iterator<Map.Entry<String, Long>> it = KEY_MILLIS_MAP.entrySet().iterator(); it.hasNext(); ) {\n            Map.Entry<String, Long> entry = it.next();\n            Long validTime = entry.getValue();\n            if (curTime >= validTime) {\n                it.remove();","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/Blankj/AndroidUtilCode/blob/7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809/lib/utilcode/src/main/java/com/blankj/utilcode/util/DebouncingUtils.java#L46-L82","documentation":"DebouncingUtils.isValid(String, long) records curTime + duration as the 'valid-until' timestamp for a key. A negative duration would set a valid-until time in the past, instantly blocking every subsequent call, so the method rejects negative durations with IllegalArgumentException. Zero is allowed and means 'no debounce'.","triggerScenarios":"Calling isValid(key, duration) where duration is negative — typically an uninitialized long field defaulting through some path, an arithmetic underflow (elapsed - now when now > elapsed), or a config value of -1 used as a sentinel.","commonSituations":"Reading a debounce window from config with a -1 'disabled' sentinel and passing it straight through; computing duration as a deadline minus current time that goes negative when the deadline already passed; copy-pasting a timeout constant that is signed elsewhere.","solutions":["Coerce the duration: use Math.max(0, duration) so negative/unset values become 'no debounce' instead of throwing.","Translate a -1 'disabled' sentinel into 0 (or skip the call entirely) at the boundary where you read the config.","Validate the duration at its source and reject/flag negative values there rather than inside isValid.","If the duration is computed from timestamps, clamp the subtraction result to >= 0."],"exampleFix":"// before\nboolean ok = DebouncingUtils.isValid(key, debounceMs); // debounceMs == -1\n\n// after\nlong duration = debounceMs < 0 ? 0 : debounceMs;\nboolean ok = DebouncingUtils.isValid(key, duration);","handlingStrategy":"validation","validationCode":"// Validate duration before debouncing\nlong duration = debounceMs;\nif (duration < 0) {\n    duration = 0; // or skip the call\n}\nboolean ok = DebouncingUtils.isValid(key, duration);","typeGuard":"// Coerce duration to a valid value\npublic static long safeDebounce(long d) {\n    return Math.max(0, d);\n}","tryCatchPattern":"try {\n    boolean ok = DebouncingUtils.isValid(key, duration);\n} catch (IllegalArgumentException e) {\n    // duration was negative; clamp and retry\n    ok = DebouncingUtils.isValid(key, Math.max(0, duration));\n}","preventionTips":["Map a -1 'disabled' config sentinel to 0 or skip the call at the read boundary.","Clamp computed durations (deadline - now) to >= 0.","Zero duration means 'no debounce' — use it deliberately rather than negatives."],"tags":["validation","debounce","argument-check"],"backgroundTag":null,"analyzedSha":"7b4caf9e5440046b3fefb63b6b6e2ead7ebaf809","analyzedAt":"2026-08-14T02:26:54.956Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}