{"record":{"id":"5e061fc54dd2c4dd","repo":"apache/dubbo","slug":"task","errorCode":null,"errorMessage":"task","messagePattern":"task","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/timer/HashedWheelTimer.java","lineNumber":386,"sourceCode":"\n            if (interrupted) {\n                Thread.currentThread().interrupt();\n            }\n        } finally {\n            INSTANCE_COUNTER.decrementAndGet();\n        }\n        return worker.unprocessedTimeouts();\n    }\n\n    @Override\n    public boolean isStop() {\n        return WORKER_STATE_SHUTDOWN == WORKER_STATE_UPDATER.get(this);\n    }\n\n    @Override\n    public Timeout newTimeout(TimerTask task, long delay, TimeUnit unit) {\n        if (task == null) {\n            throw new NullPointerException(\"task\");\n        }\n        if (unit == null) {\n            throw new NullPointerException(\"unit\");\n        }\n\n        long pendingTimeoutsCount = pendingTimeouts.incrementAndGet();\n\n        if (maxPendingTimeouts > 0 && pendingTimeoutsCount > maxPendingTimeouts) {\n            pendingTimeouts.decrementAndGet();\n            throw new RejectedExecutionException(\"Number of pending timeouts (\"\n                + pendingTimeoutsCount + \") is greater than or equal to maximum allowed pending \"\n                + \"timeouts (\" + maxPendingTimeouts + \")\");\n        }\n\n        start();\n\n        // Add the timeout to the timeout queue which will be processed on the next tick.\n        // During processing all the queued HashedWheelTimeouts will be added to the correct HashedWheelBucket.","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/timer/HashedWheelTimer.java#L368-L404","documentation":"NullPointerException thrown by HashedWheelTimer.newTimeout() when the task parameter is null. newTimeout() schedules a TimerTask to run after a delay; a null task has nothing to execute. The method fails fast before incrementing the pending timeout counter. This is standard precondition validation — task is mandatory.","triggerScenarios":"Calling timer.newTimeout(null, delay, unit) — passing a null task. Typically a programming error where the task object was not resolved or a factory method returned null.","commonSituations":"Task reference that was never assigned; conditional logic that yields null in an edge case; deserialization or lookup that returns null for the task; calling newTimeout with a placeholder before the real task is available.","solutions":["Ensure a non-null TimerTask is passed — instantiate the task before the newTimeout call.","Add a null check before calling newTimeout and handle the null case appropriately (skip, log, or use a no-op task)."],"exampleFix":"// before\nTimerTask task = taskRegistry.get(id); // may return null\ntimer.newTimeout(task, 5, TimeUnit.SECONDS);\n\n// after\nTimerTask task = taskRegistry.get(id);\nif (task == null) {\n    log.warn(\"No task found for id {}, skipping scheduling\", id);\n    return;\n}\ntimer.newTimeout(task, 5, TimeUnit.SECONDS);","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(task, \"task must not be null\");\ntimer.newTimeout(task, delay, unit);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use Objects.requireNonNull() on the task before scheduling.","Verify task lookups/factories return non-null before passing to newTimeout.","Write unit tests that assert non-null task construction in all code paths."],"tags":["timer","null-check","validation","precondition"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}