{"record":{"id":"e8fca3cf28fe3d6f","repo":"quarkusio/quarkus","slug":"no-vertx-context-found-e8fca3","errorCode":null,"errorMessage":"No Vertx context found","messagePattern":"No Vertx context found","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/scheduler/kotlin/src/main/kotlin/io/quarkus/scheduler/kotlin/runtime/AbstractCoroutineInvoker.kt","lineNumber":18,"sourceCode":"package io.quarkus.scheduler.kotlin.runtime\n\nimport io.quarkus.arc.Arc\nimport io.quarkus.scheduler.ScheduledExecution\nimport io.quarkus.scheduler.common.runtime.ScheduledInvoker\nimport io.vertx.core.Vertx\nimport java.util.concurrent.CompletionStage\nimport kotlinx.coroutines.CoroutineDispatcher\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.future.asCompletableFuture\n\nabstract class AbstractCoroutineInvoker : ScheduledInvoker {\n\n    override fun invoke(execution: ScheduledExecution): CompletionStage<Void> {\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(context = dispatcher) { invokeBean(execution) }\n            .asCompletableFuture()\n    }\n\n    abstract suspend fun invokeBean(execution: ScheduledExecution): Void\n}\n","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/scheduler/kotlin/src/main/kotlin/io/quarkus/scheduler/kotlin/runtime/AbstractCoroutineInvoker.kt#L1-L27","documentation":"AbstractCoroutineInvoker launches a Kotlin coroutine to run the @Scheduled suspend function on the ApplicationCoroutineScope, using a Vertx dispatcher. It requires the invocation to run on a Vert.x duplicated/context thread; if Vertx.currentContext() returns null the coroutine cannot be dispatched and this IllegalStateException is thrown.","triggerScenarios":"Invoking a suspend @Scheduled method from a thread that is not attached to a Vert.x context (e.g. custom invoker wiring, manual invocation of the ScheduledInvoker, or running outside the scheduled execution pipeline).","commonSituations":"Calling the invoker directly in tests without Quarkus runtime; embedding scheduler code in a non-Vert.x thread; misconfigured execution model where scheduled invocations bypass Vert.x.","solutions":["Let Quarkus invoke the scheduled method through its normal pipeline rather than calling the invoker manually","Ensure the application depends on quarkus-vertx so Vert.x context is available","In tests, use @QuarkusTest so the runtime establishes the Vert.x context","If running custom threading, wrap the call in vertx.runOnContext or executeBlocking"],"exampleFix":"// before (manual invocation in plain test)\ninvoker.invoke(execution)\n// after\n@QuarkusTest\nclass JobTest { /* trigger the schedule via Quarkus runtime */ }","handlingStrategy":"try-catch","validationCode":"if (Vertx.currentContext() == null) {\n    throw new IllegalStateException(\"invoke() must run on a Vert.x context\");\n}","typeGuard":null,"tryCatchPattern":"try { invoker.invoke(execution).toCompletableFuture().get(); }\ncatch (ExecutionException e)\n    when (e.getCause() instanceof IllegalStateException &&\n          e.getCause().getMessage().contains(\"No Vertx context\")) { /* run via Quarkus runtime */ }","preventionTips":["Invoke scheduled methods through Quarkus, never the invoker directly","Include quarkus-vertx when using coroutine invokers","Use @QuarkusTest for scheduling tests","Use vertx.runOnContext for custom threads"],"tags":["kotlin","coroutines","vertx","scheduler","quarkus"],"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-14T00:17:10.932Z"}