{"record":{"id":"dde1fffc38bc1424","repo":"quarkusio/quarkus","slug":"no-current-vertx-context-found","errorCode":null,"errorMessage":"No current Vertx context found","messagePattern":"No current Vertx context found","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java","lineNumber":384,"sourceCode":"                .orElse(null);\n    }\n\n    private static void trackOnDemandSession(Context context, String persistenceUnitName) {\n        Set<String> onDemandSessionsCreated = ContextLocals.get(context, SESSION_ON_DEMAND_OPENED_KEY, null);\n        if (onDemandSessionsCreated == null) {\n            onDemandSessionsCreated = new HashSet<>();\n            ContextLocals.put(context, SESSION_ON_DEMAND_OPENED_KEY, onDemandSessionsCreated);\n        }\n        onDemandSessionsCreated.add(persistenceUnitName);\n    }\n\n    public static Context vertxContext() {\n        Context context = Vertx.currentContext();\n        if (context != null) {\n            VertxContextSafetyToggle.validateContextIfExists(ERROR_MSG, ERROR_MSG);\n            return context;\n        } else {\n            throw new IllegalStateException(\"No current Vertx context found\");\n        }\n    }\n\n    /**\n     * Close any session open for that persistence unit (stateless or managed, there can be only one opened at a time)\n     */\n    static Uni<Void> closeSession(String persistenceUnitName) {\n        LOG.debugf(\"Closing session for Persistence Unit '%s'\", persistenceUnitName);\n        Context context = vertxContext();\n        return OPENED_SESSIONS_STATE.closeSession(context, persistenceUnitName)\n                .chain(() -> OPENED_SESSIONS_STATE_STATELESS.closeSession(context, persistenceUnitName));\n    }\n}\n","sourceCodeStart":366,"sourceCodeEnd":398,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java#L366-L398","documentation":"SessionOperations.vertxContext() returns the current Vert.x context for looking up Hibernate Reactive sessions; it throws IllegalStateException(\"No current Vertx context found\") when Vertx.currentContext() returns null, i.e. the code is running on a non-Vert.x thread (or a thread without a context) where reactive session state cannot be stored or found. Valid contexts are additionally validated with VertxContextSafetyToggle. This is a thread/context mismatch — Panache reactive operations must run on a Vert.x (duplicated) context.","triggerScenarios":"Invoking Panache reactive APIs from plain Java threads (main, executor pools, CompletableFuture.supplyAsync default pool), blocking dispatches, or any place Vert.x did not establish a current context; also from safe/invalid contexts rejected by the safety toggle path.","commonSituations":"Running reactive DB calls inside @Blocking methods; scheduling via java.util.Timer/Executors; calling Panache from a gRPC worker thread or servlet-style thread; tests running on the main thread without quarkus-test Vert.x context setup.","solutions":["Run the database work on a Vert.x context: use Quarkus-managed entry points (REST, @WithSession/@WithTransaction-annotated methods, Mutiny pipelines started from them).","Avoid @Blocking or thread-hopping around reactive session code; keep the chain within Mutiny and let Quarkus manage execution.","If you must offload, capture the current duplicated context first and re-run the work on it (context.runOnContext / VertxContextSupport).","In tests, use QuarkusTest reactive testing utilities so calls execute within the Vert.x event-loop context."],"exampleFix":"// before\nCompletableFuture.runAsync(() -> {\n    Person.findById(id); // IllegalStateException: No current Vertx context\n});\n\n// after\nUni.createFrom().item(1L)\n    .chain(id -> Person.findById(id)) // runs on the Vert.x duplicated context\n    .subscribeAsCompletionStage();","handlingStrategy":"validation","validationCode":"if (Vertx.currentContext() == null) {\n    throw new IllegalStateException(\"Not on a Vert.x thread; run Panache reactive calls within a Vert.x duplicated context (e.g. from @WithSession-annotated methods)\");\n}","typeGuard":null,"tryCatchPattern":"try { doReactiveDbWork(); } catch (IllegalStateException e) { if (e.getMessage().contains(\"No current Vertx context\")) { log.error(\"Reactive session code ran off the Vert.x event loop\", e); } throw e; }","preventionTips":["Never call Panache reactive APIs from @Blocking methods, Executors, or CompletableFuture default pools","Use Mutiny chains and Quarkus-managed entry points so execution stays on the Vert.x context","Capture and reuse the duplicated context when bridging threads (context.runOnContext / VertxContextSupport)","In tests, use QuarkusTest reactive support so calls run inside the Vert.x event loop"],"tags":["hibernate-reactive","panache","vertx-context","threading","reactive"],"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"}