{"record":{"id":"344e949facd3018d","repo":"quarkusio/quarkus","slug":"a-failure-route-cannot-be-a-blocking-route","errorCode":null,"errorMessage":"A failure route cannot be a blocking route","messagePattern":"A failure route cannot be a blocking route","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/vertx-http/deployment-spi/src/main/java/io/quarkus/vertx/http/deployment/spi/RouteBuildItem.java","lineNumber":347,"sourceCode":"         * Sets the request handler (mandatory)\n         *\n         * @param handler the handler, must not be {@code null}\n         * @return the current builder\n         */\n        public Builder withRequestHandler(Handler<RoutingContext> handler) {\n            this.handler = handler;\n            return this;\n        }\n\n        /**\n         * Sets the route as a blocking route.\n         * A blocking route handler is invoked on a worker thread, and thus is allowed to block.\n         *\n         * @return the current builder\n         */\n        public Builder asBlockingRoute() {\n            if (this.typeOfHandler == HandlerType.FAILURE) {\n                throw new IllegalArgumentException(\"A failure route cannot be a blocking route\");\n            }\n            this.typeOfHandler = HandlerType.BLOCKING;\n            return this;\n        }\n\n        /**\n         * Sets the route as a failure route.\n         * A failure route handler is invoked when an exception is thrown from a route handler.\n         *\n         * @return the current builder\n         */\n        public Builder asFailureRoute() {\n            if (this.typeOfHandler == HandlerType.BLOCKING) {\n                throw new IllegalArgumentException(\"A blocking route cannot be a failure route\");\n            }\n            this.typeOfHandler = HandlerType.FAILURE;\n            return this;\n        }","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/vertx-http/deployment-spi/src/main/java/io/quarkus/vertx/http/deployment/spi/RouteBuildItem.java#L329-L365","documentation":"RouteBuildItem.Builder.asBlockingRoute() marks the route's handler to run on a worker thread; failure routes (handler type FAILURE) are incompatible with this mode, so the builder refuses the change with an IllegalArgumentException.","triggerScenarios":"Builder chain calls asFailureRoute() then asBlockingRoute() on the same builder (typeOfHandler == HandlerType.FAILURE).","commonSituations":"Copy-pasted builder chains toggling both handler types; refactoring an existing failure route to be blocking; a utility method that applies asBlockingRoute unconditionally.","solutions":["Remove asFailureRoute() from the builder chain if a blocking route is intended","Remove asBlockingRoute() if the route must remain a failure route","If blocking work is needed in a failure handler, offload via executeBlocking/Uni inside the handler instead"],"exampleFix":"// before\nRouteBuildItem.builder().route(route).asFailureRoute().asBlockingRoute().build()\n// after\nRouteBuildItem.builder().route(route).asBlockingRoute().build()","handlingStrategy":"validation","validationCode":"// decide the handler type once; never apply both\nboolean failure = ...;\nRouteBuildItem.Builder b = RouteBuildItem.builder().route(route);\nif (failure) b.asFailureRoute(); else b.asBlockingRoute();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set exactly one of asBlockingRoute/asFailureRoute per builder","Keep builder chains linear and reviewed for duplicate handler-type calls","Document handler type in shared route-building helpers"],"tags":["build-time","routes","validation","argument-illegal"],"backgroundTag":"incompatible-route-config","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"}