{"record":{"id":"cb7842157f9d8ea5","repo":"quarkusio/quarkus","slug":"a-task-is-already-pending","errorCode":null,"errorMessage":"A task is already pending","messagePattern":"A task is already pending","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"independent-projects/qute/debug/src/main/java/io/quarkus/qute/debug/agent/RemoteThread.java","lineNumber":367,"sourceCode":"     * compatibility with request-bound state.\n     * </p>\n     *\n     * @param action the task to execute within the render thread context.\n     *        It should return a {@link CompletableFuture} representing the computation result.\n     * @return a {@link CompletableFuture} containing the result of the executed task\n     * @throws IllegalStateException if the thread is not currently suspended or if another\n     *         evaluation task is already pending\n     */\n    public CompletableFuture<Object> evaluateInRenderThread(Callable<CompletableFuture<Object>> action) {\n        synchronized (lock) {\n            // Ensure the render thread is suspended before executing any task\n            if (this.state != DebuggerState.SUSPENDED) {\n                throw new IllegalStateException(\"Thread not suspended\");\n            }\n\n            // Prevent concurrent evaluation tasks from overlapping\n            if (pendingTask != null) {\n                throw new IllegalStateException(\"A task is already pending\");\n            }\n\n            // Schedule the evaluation task to be executed by the render thread\n            pendingTask = action;\n            taskResult = null;\n\n            // Wake up the suspended render thread so it can pick up and execute the task\n            lock.notifyAll();\n\n            // Wait for the render thread to process and complete the pending task\n            boolean intr = false;\n            try {\n                while (pendingTask != null) {\n                    try {\n                        lock.wait();\n                    } catch (InterruptedException e) {\n                        intr = true;\n                    }","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/qute/debug/src/main/java/io/quarkus/qute/debug/agent/RemoteThread.java#L349-L385","documentation":"evaluateInRenderThread() allows only one in-flight evaluation per RemoteThread. It throws IllegalStateException('A task is already pending') when a second evaluation is scheduled before the previous one's pendingTask is consumed by the render thread.","triggerScenarios":"Issuing two overlapping evaluate requests on the same suspended render thread — e.g. a DAP client sending multiple evaluateRequests (watch expressions, hover, repl) before the first completes.","commonSituations":"IDE watch panels firing several evaluations at once on breakpoint hit; batch variable evaluation scripts; a slow evaluation (blocking expression) causing the UI to re-issue requests.","solutions":["Serialize evaluations: wait for the previous evaluateInRenderThread() CompletableFuture to complete before submitting another.","Catch IllegalStateException and retry after the pending task finishes.","Queue evaluations per thread instead of issuing them concurrently.","Investigate why the previous evaluation never completed (a blocking/long-running expression can wedge pendingTask)."],"exampleFix":"// before\nthread.evaluateInRenderThread(a1);\nthread.evaluateInRenderThread(a2); // throws\n// after\nthread.evaluateInRenderThread(a1).thenRun(() -> thread.evaluateInRenderThread(a2));","handlingStrategy":"validation","validationCode":"synchronized (thread) {\n    if (pendingEvaluationInFlight) throw new IllegalStateException(\"serialize evaluations\");\n    pendingEvaluationInFlight = true;\n}\nthread.evaluateInRenderThread(action).whenComplete((r, e) -> pendingEvaluationInFlight = false);","typeGuard":null,"tryCatchPattern":"try {\n    return thread.evaluateInRenderThread(action).get();\n} catch (IllegalStateException e) {\n    if (\"A task is already pending\".equals(e.getMessage())) {\n        // queue or retry after the current evaluation completes\n    }\n    throw e;\n}","preventionTips":["Serialize evaluations per thread (no concurrent evaluate calls)","Queue watch/hover evaluations instead of firing in parallel","Investigate evaluations that never complete — they wedge the pending slot"],"tags":["qute","debugger","evaluate","concurrency","pending-task"],"backgroundTag":"operation-already-pending","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}