{"record":{"id":"febb3cb1a29bd9dd","repo":"quarkusio/quarkus","slug":"no-vertx-context-found-febb3c","errorCode":null,"errorMessage":"No Vertx context found","messagePattern":"No Vertx context found","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest-kotlin/runtime/src/main/kotlin/org/jboss/resteasy/reactive/server/runtime/kotlin/FlowToPublisherHandler.kt","lineNumber":23,"sourceCode":"import jakarta.enterprise.inject.spi.CDI\nimport java.util.concurrent.Executor\nimport kotlinx.coroutines.CoroutineDispatcher\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.launch\nimport org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext\nimport org.jboss.resteasy.reactive.server.spi.ServerRestHandler\n\nclass FlowToPublisherHandler : ServerRestHandler {\n\n    private val originalTCCL: ClassLoader = Thread.currentThread().contextClassLoader\n\n    override fun handle(requestContext: ResteasyReactiveRequestContext?) {\n        val result = requestContext!!.result\n        if (result is Flow<*>) {\n            val requestScope = requestContext.captureCDIRequestScope()\n            val dispatcher: CoroutineDispatcher =\n                Vertx.currentContext()?.let { VertxDispatcher(it, requestScope, requestContext) }\n                    ?: throw IllegalStateException(\"No Vertx context found\")\n\n            val coroutineScope = CDI.current().select(ApplicationCoroutineScope::class.java)\n            requestContext.suspend()\n            coroutineScope.get().launch(context = dispatcher) {\n                // ensure the proper CL is not lost in dev-mode\n                Thread.currentThread().contextClassLoader = originalTCCL\n                requestContext.result = result.asMulti()\n                // run in a direct invocation executor to run the rest of the invocation in the\n                // co-route scope\n                // feels a bit fragile, but let's see how it goes\n                requestContext.resume(Executor { it.run() })\n            }\n        }\n    }\n}\n","sourceCodeStart":5,"sourceCodeEnd":39,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest-kotlin/runtime/src/main/kotlin/org/jboss/resteasy/reactive/server/runtime/kotlin/FlowToPublisherHandler.kt#L5-L39","documentation":"FlowToPublisherHandler adapts a Kotlin Flow result into a reactive Publisher for RESTEasy Reactive. It needs the Vert.x context to construct a VertxDispatcher; if Vertx.currentContext() is null it throws IllegalStateException(\"No Vertx context found\"). Same family as the coroutine handler context error but on the Flow-to-Publisher path.","triggerScenarios":"An endpoint returning Flow<...> is processed on a thread without an active Vert.x context, so VertxDispatcher cannot be created.","commonSituations":"Flow-returning endpoints invoked via blocking dispatch or custom thread pools; tests calling resource methods directly; threading extensions stripping the Vert.x context before result handling.","solutions":["Ensure Flow-returning endpoints are served via the standard HTTP pipeline on Vert.x event loops","Avoid @Blocking on Flow-returning endpoints","Call endpoints through HTTP/RestAssured in tests instead of direct method invocation","Upgrade Quarkus for improved context propagation"],"exampleFix":"// before\n@Blocking\n@GET\nfun stream(): Flow<Item> = flow { ... }\n// after\n@GET\nfun stream(): Flow<Item> = flow { ... }","handlingStrategy":"try-catch","validationCode":"if (io.vertx.core.Vertx.currentContext() == null) {\n    throw IllegalStateException(\"Flow endpoint handled without Vert.x context\")\n}","typeGuard":"fun canAdaptFlow(): Boolean = io.vertx.core.Vertx.currentContext() != null","tryCatchPattern":"try {\n    flowHandler.handle(requestContext)\n} catch (e: IllegalStateException) {\n    if (e.message?.contains(\"No Vertx context found\") == true) {\n        requestContext.handleException(e, true)\n    } else throw e\n}","preventionTips":["Do not annotate Flow-returning endpoints with @Blocking","Test Flow endpoints through HTTP, not direct invocation","Keep threading/dispatch customizations within Vert.x context propagation rules"],"tags":["kotlin","flow","vertx","threading","resteasy-reactive"],"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"}