{"record":{"id":"886207a8ac3ee137","repo":"quarkusio/quarkus","slug":"no-vertx-context-found-consider-using-nonblockin","errorCode":null,"errorMessage":"No Vertx context found. Consider using @NonBlocking on the caller method, or make sure the upstream emits items on the Vert.x context","messagePattern":"No Vertx context found\\. Consider using @NonBlocking on the caller method, or make sure the upstream emits items on the Vert\\.x context","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/smallrye-reactive-messaging/kotlin/src/main/kotlin/io/quarkus/smallrye/reactivemessaging/runtime/kotlin/AbstractSubscribingCoroutineInvoker.kt","lineNumber":16,"sourceCode":"package io.quarkus.smallrye.reactivemessaging.runtime.kotlin\n\nimport io.quarkus.arc.Arc\nimport io.smallrye.reactive.messaging.Invoker\nimport io.vertx.core.Vertx\nimport java.util.concurrent.CompletableFuture\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.future.asCompletableFuture\n\nabstract class AbstractSubscribingCoroutineInvoker(private val beanInstance: Any) : Invoker {\n\n    override fun invoke(vararg args: Any?): CompletableFuture<Any?> {\n        val coroutineScope = Arc.container().instance(ApplicationCoroutineScope::class.java).get()\n        val dispatcher =\n            Vertx.currentContext()?.let(::VertxDispatcher)\n                ?: throw IllegalStateException(\n                    \"No Vertx context found. Consider using @NonBlocking on the caller method, or make sure the upstream emits items on the Vert.x context\"\n                )\n\n        return coroutineScope\n            .async(context = dispatcher) {\n                try {\n                    invokeBean(beanInstance, args)\n                } finally {\n                    dispatcher.cleanup()\n                }\n            }\n            .asCompletableFuture()\n    }\n\n    abstract suspend fun invokeBean(beanInstance: Any, args: Array<out Any?>): Any?\n}\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/smallrye-reactive-messaging/kotlin/src/main/kotlin/io/quarkus/smallrye/reactivemessaging/runtime/kotlin/AbstractSubscribingCoroutineInvoker.kt#L1-L33","documentation":"The coroutine invoker for a suspend Reactive Messaging method must run on a Vert.x context: it derives its dispatcher from Vertx.currentContext(). When invoked with no current Vertx context it throws IllegalStateException, advising @NonBlocking or ensuring upstream items are emitted on the Vert.x context.","triggerScenarios":"A suspend @Incoming mediator invoked from a thread without a Vert.x duplicated context, e.g. a custom executor, plain worker thread, or non-blocking requirement violated by @Blocking upstream.","commonSituations":"Calling the invoker manually in tests; upstream emitter running on a non-Vert.x thread (e.g. timer/scheduled executor); misusing @Blocking on the coroutine method.","solutions":["Annotate the calling method with @NonBlocking so it runs on the Vert.x (event-loop) context.","Make sure the upstream publisher emits on a Vert.x context (use runSubscriptionOn / emit on event loop).","Remove @Blocking from the suspend method; @Blocking runs it on a worker thread without Vert.x context."],"exampleFix":"// before\n@Blocking\n@Incoming(\"in\")\nsuspend fun handle(p: String) { ... }\n// after\n@NonBlocking\n@Incoming(\"in\")\nsuspend fun handle(p: String) { ... }","handlingStrategy":"validation","validationCode":"// Guard in the invoker before starting the coroutine:\nif (Vertx.currentContext() == null) {\n    throw IllegalStateException(\"invoke must be called on a Vert.x context\")\n}","typeGuard":null,"tryCatchPattern":"try {\n    invoker.invoke(args).get()\n} catch (e: ExecutionException) {\n    val cause = e.cause\n    if (cause is IllegalStateException && cause.message?.contains(\"No Vertx context\") == true) {\n        // rerun on a Vert.x duplicated context\n        vertx.runOnContext { invoker.invoke(args) }\n    } else throw cause\n}","preventionTips":["Annotate coroutine mediators (or their callers) with @NonBlocking.","Avoid @Blocking on suspend methods.","Emit upstream items on the Vert.x context (e.g. Multi.createFrom().emitter with runSubscriptionOn the Vert.x executor)."],"tags":["kotlin","coroutines","vertx","context","reactive-messaging"],"backgroundTag":"missing-vertx-context","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"}