{"record":{"id":"5a02751a49e2d276","repo":"quarkusio/quarkus","slug":"unsupported-type-jaxrsannotationofparam-name","errorCode":null,"errorMessage":"Unsupported type '${jaxRSAnnotationOfParam.name()}' used as an annotation in constructor of class '${resourceDotName}'","messagePattern":"Unsupported type '(.+?)' used as an annotation in constructor of class '(.+?)'","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/CustomResourceProducersGenerator.java","lineNumber":267,"sourceCode":"                            if (!parameterType.name().equals(ResteasyReactiveDotNames.STRING)) {\n                                // TODO: do we need to support converters here?\n                                throw new IllegalArgumentException(\"Parameter: \" + i + \" of the constructor of class '\"\n                                        + resourceDotName + \"' which is annotated with '\" + jaxRSAnnotationOfParam.name()\n                                        + \"' can only be of type String\");\n                            }\n                            CtorParamData.CustomProducerParameterType customProducerParameterType;\n                            if (jaxRSAnnotationOfParam.name().equals(ResteasyReactiveDotNames.QUERY_PARAM)) {\n                                customProducerParameterType = CtorParamData.CustomProducerParameterType.QUERY;\n                            } else if (jaxRSAnnotationOfParam.name().equals(ResteasyReactiveDotNames.HEADER_PARAM)) {\n                                customProducerParameterType = CtorParamData.CustomProducerParameterType.HEADER;\n                            } else if (jaxRSAnnotationOfParam.name().equals(ResteasyReactiveDotNames.PATH_PARAM)) {\n                                customProducerParameterType = CtorParamData.CustomProducerParameterType.PATH;\n                            } else if (jaxRSAnnotationOfParam.name().equals(ResteasyReactiveDotNames.MATRIX_PARAM)) {\n                                customProducerParameterType = CtorParamData.CustomProducerParameterType.MATRIX;\n                            } else if (jaxRSAnnotationOfParam.name().equals(ResteasyReactiveDotNames.COOKIE_PARAM)) {\n                                customProducerParameterType = CtorParamData.CustomProducerParameterType.COOKIE;\n                            } else {\n                                throw new IllegalStateException(\"Unsupported type '\" + jaxRSAnnotationOfParam.name()\n                                        + \"' used as an annotation in constructor of class '\" + resourceDotName + \"'\");\n                            }\n                            String name = jaxRSAnnotationOfParam.value().asString(); // all the types we handle have the same annotation method\n                            ctorParamData.add(new CtorParamData(customProducerParameterType, parameterType, name));\n                        }\n                    }\n                }\n                List<String> producerMethodParameterTypes = new ArrayList<>(ctor.parametersCount());\n                for (CtorParamData ctorParamDatum : ctorParamData) {\n                    if (ctorParamDatum.getCustomProducerParameterType() == CtorParamData.CustomProducerParameterType.OTHER) {\n                        producerMethodParameterTypes.add(ctorParamDatum.getParameterType().name().toString());\n                    }\n                }\n\n                String methodName = \"producer_\" + resourceDotName.withoutPackagePrefix()\n                        + HashUtil.sha1(resourceDotName.toString());\n                try (MethodCreator m = c.getMethodCreator(methodName, resourceDotName.toString(),\n                        producerMethodParameterTypes.toArray(new String[0]))) {","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/CustomResourceProducersGenerator.java#L249-L285","documentation":"The generator for resource classes with non-default constructors only knows how to map @QueryParam, @PathParam, @MatrixParam and @CookieParam constructor annotations to request values. A parameter annotated with any other JAX-RS annotation (e.g. @HeaderParam or @Context) reaches the mapping switch's else branch and throws this IllegalStateException.","triggerScenarios":"A resource class has a non-default constructor with a parameter annotated with @HeaderParam, @Context, @FormParam or another annotation that is not one of the four supported parameter annotations, and the annotation is treated as a JAX-RS parameter annotation during the build.","commonSituations":"Injecting headers via constructor because query/path worked in the constructor before; trying to @Context-inject UriInfo or HttpHeaders in a resource constructor.","solutions":["Restrict constructor parameter annotations to @QueryParam, @PathParam, @MatrixParam or @CookieParam","Inject @HeaderParam/@Context values as method parameters or resource fields instead of constructor parameters","Use @Inject of CDI beans (e.g. injected HttpHeaders/UriInfo providers) rather than JAX-RS @Context in the constructor"],"exampleFix":"// before\npublic MyResource(@HeaderParam(\"X-Tenant\") String tenant) { ... }\n// after\npublic MyResource() { ... }\npublic Response get(@HeaderParam(\"X-Tenant\") String tenant) { ... }","handlingStrategy":"validation","validationCode":"Set<String> supported = Set.of(\"jakarta.ws.rs.QueryParam\",\"jakarta.ws.rs.PathParam\",\"jakarta.ws.rs.MatrixParam\",\"jakarta.ws.rs.CookieParam\");\nfor (Parameter p : ctor.getParameters()) {\n    for (Annotation a : p.getAnnotations()) {\n        String n = a.annotationType().getName();\n        if (n.startsWith(\"jakarta.ws.rs.\") && !supported.contains(n))\n            throw new IllegalStateException(n + \" is not supported on resource constructor parameters\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use @QueryParam/@PathParam/@MatrixParam/@CookieParam in resource constructors","Inject @HeaderParam and @Context values via method parameters or fields instead","Use CDI @Inject for provider beans (HttpHeaders, UriInfo) rather than @Context in constructors"],"tags":["jax-rs","resteasy-reactive","quarkus","header-param","context-injection"],"backgroundTag":"unsupported-constructor-param-annotation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}