{"record":{"id":"69940abe38bcf131","repo":"quarkusio/quarkus","slug":"vertxcontextsupport-subscribeandawait-must-not-b","errorCode":null,"errorMessage":"VertxContextSupport#subscribeAndAwait() must not be called on an event loop!","messagePattern":"VertxContextSupport#subscribeAndAwait\\(\\) must not be called on an event loop!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/vertx/runtime/src/main/java/io/quarkus/vertx/VertxContextSupport.java","lineNumber":138,"sourceCode":"                    return callable.call();\n                } finally {\n                    if (terminate) {\n                        requestContext.terminate();\n                    }\n                }\n            }, false).toCompletionStage();\n        });\n    }\n\n    private static Context getContext(boolean blocking) {\n        Context context = Vertx.currentContext();\n        if (context == null) {\n            Vertx vertx = VertxCoreRecorder.getVertx().get();\n            context = VertxContext.getOrCreateDuplicatedContext(vertx);\n        } else {\n            // Executed on a vertx thread...\n            if (!blocking && Context.isOnEventLoopThread()) {\n                throw new IllegalStateException(\"VertxContextSupport#subscribeAndAwait() must not be called on an event loop!\");\n            }\n            context = VertxContext.getOrCreateDuplicatedContext(context);\n        }\n        return context;\n    }\n\n}\n","sourceCodeStart":120,"sourceCodeEnd":146,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/VertxContextSupport.java#L120-L146","documentation":"VertxContextSupport.subscribeAndAwait() blocks the current thread waiting for a CompletionStage to complete, which is illegal on a Vert.x event loop thread. VertxContextSupport.getContext detects this combination (non-blocking call attempted on an event loop thread) and throws IllegalStateException to avoid deadlocking the event loop.","triggerScenarios":"Calling code that ultimately reaches VertxContextSupport.subscribeAndAwait() (e.g. blocking bridging of a Uni/CompletionStage) while the current thread is a Vert.x event loop thread; getContext throws when !blocking && Context.isOnEventLoopThread().","commonSituations":"Calling .await() or .subscribeAsCompletionStage().get() style helpers inside an event-loop handler, a synchronous REST resource method running on the event loop, or a sync startup/observer method that blocks on a Uni.","solutions":["Move the call to a worker thread: annotate the method @Blocking or offload via Uni.runSubscriptionOn(Executors.newSingleThreadExecutor())","Use non-blocking composition (chain the Uni/CompletionStage with map/chain) instead of awaiting","If running under RESTEasy Reactive, make the endpoint return Uni<?> instead of blocking"],"exampleFix":"// before\nString result = vertxContextSupport.subscribeAndAwait(uni); // on event loop\n\n// after\n@Blocking\nString handler() { return vertxContextSupport.subscribeAndAwait(uni); }\n// or: return uni.await().atMost(Duration.ofSeconds(5)) inside a @Blocking method;","handlingStrategy":"validation","validationCode":"import io.vertx.core.Context;\nif (Context.isOnEventLoopThread()) {\n    throw new IllegalStateException(\"Move subscribeAndAwait to a worker thread or use non-blocking composition\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never call .await()/blocking getters inside event-loop handlers; annotate with @Blocking instead","Return Uni/CompletionStage from reactive endpoints instead of blocking","Guard shared utility methods with Context.isOnEventLoopThread() checks"],"tags":["vertx","event-loop","blocking","mutiny"],"backgroundTag":"blocking-on-event-loop","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"}