{"record":{"id":"4da02bfd9a405afb","repo":"quarkusio/quarkus","slug":"no-vertx-context-found-4da02b","errorCode":null,"errorMessage":"No Vertx context found","messagePattern":"No Vertx context found","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/websockets-next/kotlin/src/main/kotlin/io/quarkus/websockets/next/runtime/kotlin/CoroutineInvoker.kt","lineNumber":22,"sourceCode":"import io.smallrye.mutiny.Uni\nimport io.smallrye.mutiny.coroutines.asUni\nimport io.vertx.core.Vertx\nimport jakarta.enterprise.invoke.Invoker\nimport kotlin.coroutines.resume\nimport kotlin.coroutines.resumeWithException\nimport kotlin.coroutines.suspendCoroutine\nimport kotlinx.coroutines.CoroutineDispatcher\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.async\n\nobject CoroutineInvoker {\n    @JvmStatic\n    @OptIn(ExperimentalCoroutinesApi::class)\n    fun <T, U> inNewCoroutine(instance: T, arguments: Array<Any?>, invoker: Invoker<T, U>): Uni<U> {\n        val coroutineScope = Arc.container().instance(ApplicationCoroutineScope::class.java).get()\n        val dispatcher: CoroutineDispatcher =\n            Vertx.currentContext()?.let(::VertxDispatcher)\n                ?: throw IllegalStateException(\"No Vertx context found\")\n\n        return coroutineScope\n            .async<U>(context = dispatcher) {\n                suspendCoroutine { continuation ->\n                    arguments[arguments.size - 1] = continuation\n                    try {\n                        continuation.resume(invoker.invoke(instance, arguments))\n                    } catch (e: Exception) {\n                        continuation.resumeWithException(e)\n                    }\n                }\n            }\n            .asUni()\n    }\n}\n","sourceCodeStart":4,"sourceCodeEnd":38,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/websockets-next/kotlin/src/main/kotlin/io/quarkus/websockets/next/runtime/kotlin/CoroutineInvoker.kt#L4-L38","documentation":"CoroutineInvoker.inNewCoroutine launches the endpoint callback on a coroutine dispatched by the current Vert.x context. If Vertx.currentContext() returns null (the code is not running on a Vert.x/duplicated context), it throws IllegalStateException 'No Vertx context found'.","triggerScenarios":"Invoking a Kotlin suspend WebSockets Next callback from a thread that is not a Vert.x worker/event-loop thread, e.g. from a plain executor, a @Blocking method on a platform thread outside the Vert.x context, or during tests without an active Vertx context.","commonSituations":"Calling the endpoint method directly from a scheduler thread or unit test; custom threading that breaks the Vert.x context propagation chain.","solutions":["Ensure the callback is invoked on a Vert.x-managed thread (Vertx.getOrCreateContext context exists)","Do not call endpoint callbacks directly from custom thread pools; route through the WebSockets Next invocation machinery","In tests, use @RunOnVertxContext or Quarkus test harness so a Vertx context is active"],"exampleFix":"// before\nexecutor.submit { endpoint.onMessage(msg) } // no Vertx context\n// after\nvertx.runOnContext { endpoint.onMessage(msg) } // or rely on WebSockets Next dispatch","handlingStrategy":"try-catch","validationCode":"val ctx = Vertx.currentContext()\nrequireNotNull(ctx) { \"inNewCoroutine must run on a Vert.x context\" }","typeGuard":"fun onVertxContext(): Boolean = Vertx.currentContext() != null","tryCatchPattern":"try {\n    CoroutineInvoker.inNewCoroutine(instance, args, invoker)\n} catch (e: IllegalStateException) {\n    // not on a Vert.x thread; reroute via vertx.runOnContext { ... }\n}","preventionTips":["Never invoke endpoint callbacks from plain executors or raw test threads","Run tests under the Quarkus Vert.x test context (e.g. @RunOnVertxContext)"],"tags":["kotlin","coroutines","vertx","threading"],"backgroundTag":"no-vertx-context","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}