{"record":{"id":"50588f06ba72d500","repo":"quarkusio/quarkus","slug":"route-filter-method-must-return-void-method-s","errorCode":null,"errorMessage":"Route filter method must return void [method: %s, bean: %s]","messagePattern":"Route filter method must return void \\[method: (.+?), bean: (.+?)\\]","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/reactive-routes/deployment/src/main/java/io/quarkus/vertx/web/deployment/ReactiveRoutesProcessor.java","lineNumber":518,"sourceCode":"                    priorityValue != null ? priorityValue.asInt() : RouteFilter.DEFAULT_PRIORITY));\n        }\n\n        detectConflictingRoutes(matchers);\n    }\n\n    @BuildStep\n    AutoAddScopeBuildItem autoAddScope() {\n        return AutoAddScopeBuildItem.builder()\n                .containsAnnotations(DotNames.ROUTE,\n                        DotNames.ROUTES,\n                        DotNames.ROUTE_FILTER)\n                .defaultScope(BuiltinScope.SINGLETON)\n                .reason(\"Found route handler business methods\").build();\n    }\n\n    private void validateRouteFilterMethod(BeanInfo bean, MethodInfo method) {\n        if (!method.returnType().kind().equals(Type.Kind.VOID)) {\n            throw new IllegalStateException(\n                    String.format(\"Route filter method must return void [method: %s, bean: %s]\", method, bean));\n        }\n        List<Type> params = method.parameterTypes();\n        if (params.size() != 1 || !params.get(0).name()\n                .equals(DotNames.ROUTING_CONTEXT)) {\n            throw new IllegalStateException(String.format(\n                    \"Route filter method must accept exactly one parameter of type %s: %s [method: %s, bean: %s]\",\n                    DotNames.ROUTING_CONTEXT, params, method, bean));\n        }\n    }\n\n    private void validateRouteMethod(BeanInfo bean, MethodInfo method,\n            TransformedAnnotationsBuildItem transformedAnnotations, IndexView index, AnnotationInstance routeAnnotation) {\n        List<Type> params = method.parameterTypes();\n        if (params.isEmpty()) {\n            if (method.returnType().kind() == Kind.VOID && params.isEmpty()) {\n                throw new IllegalStateException(String.format(\n                        \"Route method that returns void must accept at least one injectable parameter [method: %s, bean: %s]\",","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/reactive-routes/deployment/src/main/java/io/quarkus/vertx/web/deployment/ReactiveRoutesProcessor.java#L500-L536","documentation":"Route filter methods (@RouteFilter) must return void because they work by mutating the RoutingContext/continuing the chain, not by returning a value. validateRouteFilterMethod throws IllegalStateException during build if a filter method declares a non-void return type.","triggerScenarios":"Annotating a @RouteFilter method that returns a value (e.g. String, Response, Uni) instead of void.","commonSituations":"Returning a value from a filter by habit from JAX-RS filters; converting an endpoint method into a filter while keeping its return type; forgetting to change the signature when adding @RouteFilter.","solutions":["Change the @RouteFilter method return type to void","If a value must be produced, store it in the RoutingContext via rc.put(...) instead of returning it","Rename the method so IDE quick-fixes don't reintroduce a return type"],"exampleFix":"// before\n@RouteFilter(100)\npublic String myFilter(RoutingContext rc) { ... }\n// after\n@RouteFilter(100)\npublic void myFilter(RoutingContext rc) { rc.next(); }","handlingStrategy":"validation","validationCode":"Method m = bean.getClass().getMethod(\"myFilter\", RoutingContext.class);\nif (m.isAnnotationPresent(RouteFilter.class)\n        && m.getReturnType() != void.class) {\n    throw new IllegalStateException(\"@RouteFilter must return void\");\n}","typeGuard":"boolean isValidRouteFilter(Method m) {\n    return m.getReturnType() == void.class\n        && m.getParameterCount() == 1\n        && m.getParameterTypes()[0] == RoutingContext.class;\n}","tryCatchPattern":null,"preventionTips":["Always declare @RouteFilter methods as void","Check route filter signature in code reviews","Use a project template/snippet for filters"],"tags":["quarkus","reactive-routes","route-filter","build-time"],"backgroundTag":"invalid-route-filter-signature","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"}