{"record":{"id":"5aa14229f1b24971","repo":"quarkusio/quarkus","slug":"suspend-method-targetmethod-name-of-class","errorCode":null,"errorMessage":"Suspend method '${targetMethod.name()} of class '${targetMethod.declaringClass().name()}' cannot be used as a request filter as it does not declare 'void', 'Response', 'RestResponse' as its return type.","messagePattern":"Suspend method '(.+?) of class '(.+?)' cannot be used as a request filter as it does not declare 'void', 'Response', 'RestResponse' as its return type\\.","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/CustomFilterGenerator.java","lineNumber":110,"sourceCode":"        checkModifiers(targetMethod, ResteasyReactiveServerDotNames.SERVER_REQUEST_FILTER);\n        if (KotlinUtils.isSuspendMethod(targetMethod)) {\n            return generateRequestFilterForSuspendedMethod(targetMethod, classOutput, isOptionalFilter.test(targetMethod));\n        }\n        return generateStandardRequestFilter(targetMethod, classOutput, isOptionalFilter.test(targetMethod));\n    }\n\n    private String generateRequestFilterForSuspendedMethod(MethodInfo targetMethod, ClassOutput classOutput,\n            boolean checkForOptionalBean) {\n        DotName returnDotName = determineReturnDotNameOfSuspendMethod(targetMethod);\n        ReturnType returnType;\n        if (returnDotName.equals(VOID)) {\n            returnType = ReturnType.VOID;\n        } else if (returnDotName.equals(RESPONSE)) {\n            returnType = ReturnType.RESPONSE;\n        } else if (returnDotName.equals(REST_RESPONSE)) {\n            returnType = ReturnType.REST_RESPONSE;\n        } else {\n            throw new RuntimeException(\"Suspend method '\" + targetMethod.name() + \" of class '\"\n                    + targetMethod.declaringClass().name()\n                    + \"' cannot be used as a request filter as it does not declare 'void', 'Response', 'RestResponse' as its return type.\");\n        }\n\n        String generatedClassName = getGeneratedClassName(targetMethod, ResteasyReactiveServerDotNames.SERVER_REQUEST_FILTER);\n        ClassInfo declaringClass = targetMethod.declaringClass();\n        DotName declaringClassName = declaringClass.name();\n        try (ClassCreator cc = ClassCreator.builder().classOutput(classOutput)\n                .className(generatedClassName)\n                .superClass(ABSTRACT_SUSPENDED_REQ_FILTER)\n                .build()) {\n            FieldDescriptor delegateField = generateConstructorAndDelegateField(cc, declaringClass,\n                    ABSTRACT_SUSPENDED_REQ_FILTER, additionalBeanAnnotations, checkForOptionalBean);\n\n            // generate the implementation of the 'doFilter' method\n            MethodCreator doFilterMethod = cc.getMethodCreator(\"doFilter\", Object.class.getName(),\n                    ResteasyReactiveContainerRequestContext.class.getName(), ResteasyReactiveDotNames.CONTINUATION.toString());\n            ResultHandle delegate = doFilterMethod.readInstanceField(delegateField, doFilterMethod.getThis());","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/CustomFilterGenerator.java#L92-L128","documentation":"CustomFilterGenerator's generateRequestFilterForSuspendedMethod handles Kotlin suspend request filter methods by unwrapping their Continuation return type. After unwrapping, the underlying return type must be void, Response, or RestResponse; anything else throws this RuntimeException and fails the Quarkus build.","triggerScenarios":"A Kotlin suspend fun used as a @ServerRequestFilter whose Continuation-wrapped return type is something other than void/Unit, Response, or RestResponse — e.g. returning String, Int, or a custom type.","commonSituations":"Kotlin developers writing suspend filters that return a value instead of mutating the request context, or returning Boolean (the dedicated @ServerRequestFilter filterOnly variant should be used instead).","solutions":["Change the suspend filter to return Unit (void) and mutate the ContainerRequestContext or call context.abortWith(...) instead","Return Response or RestResponse from the suspend filter for early termination","If you want to accept/abort without a response, use the non-suspend filter returning void or the documented Boolean-based pattern","Remove @ServerRequestFilter if the method is not a filter"],"exampleFix":"// before (Kotlin)\n@ServerRequestFilter\nsuspend fun filter(ctx: ContainerRequestContext): String { ... }\n\n// after\n@ServerRequestFilter\nsuspend fun filter(ctx: ContainerRequestContext) {\n    ctx.abortWith(Response.status(401).build())\n}","handlingStrategy":"validation","validationCode":"// Kotlin: check suspend request filter return before build\nval m = clazz.declaredMethods.first { it.isAnnotationPresent(ServerRequestFilter::class.java) }\nval allowed = setOf(Void.TYPE, Response::class.java, RestResponse::class.java)\nrequire(m.returnType in allowed) { \"Suspend request filter must return Unit, Response, or RestResponse: $m\" }\n","typeGuard":"fun isValidSuspendRequestFilter(m: Method): Boolean =\n    m.returnType == Void.TYPE || m.returnType == Response::class.java || m.returnType == RestResponse::class.java\n","tryCatchPattern":null,"preventionTips":["In Kotlin suspend filters, return Unit and mutate/abort the request context instead of returning values","Return Response or RestResponse only for early-abort suspend filters","Keep filter signatures minimal and copy them from the Quarkus documentation examples"],"tags":["quarkus","resteasy-reactive","kotlin","filter","build-time"],"backgroundTag":"invalid-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"}