{"record":{"id":"8263b0a04511d468","repo":"quarkusio/quarkus","slug":"parameter-i-of-the-constructor-of-class-res-8263b0","errorCode":null,"errorMessage":"Parameter: ${i} of the constructor of class '${resourceDotName}' which is annotated with '${jaxRSAnnotationOfParam.name()}' can only be of type String","messagePattern":"Parameter: (.+?) of the constructor of class '(.+?)' which is annotated with '(.+?)' can only be of type String","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/CustomResourceProducersGenerator.java","lineNumber":251,"sourceCode":"                        List<AnnotationInstance> paramAnnotations = paramIndexToAnnotations.get(i);\n                        List<AnnotationInstance> jaxRSAnnotationsOfParam = new ArrayList<>(paramAnnotations.size());\n                        for (AnnotationInstance paramAnnotation : paramAnnotations) {\n                            if (ResteasyReactiveDotNames.RESOURCE_CTOR_PARAMS_THAT_NEED_HANDLING\n                                    .contains(paramAnnotation.name())) {\n                                jaxRSAnnotationsOfParam.add(paramAnnotation);\n                            }\n                        }\n                        if (jaxRSAnnotationsOfParam.isEmpty()) {\n                            ctorParamData\n                                    .add(new CtorParamData(CtorParamData.CustomProducerParameterType.OTHER, parameterType));\n                        } else if (jaxRSAnnotationsOfParam.size() > 1) {\n                            throw new IllegalArgumentException(\"Parameter: \" + i + \" of the constructor of class '\"\n                                    + resourceDotName + \"' contains multiple JAX-RS annotations, which is not valid\");\n                        } else {\n                            AnnotationInstance jaxRSAnnotationOfParam = jaxRSAnnotationsOfParam.iterator().next();\n                            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                            }","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/CustomResourceProducersGenerator.java#L233-L269","documentation":"When Quarkus generates custom producers for resource classes with non-default constructors, constructor parameters carrying a JAX-RS parameter annotation must be of type java.lang.String; the generated bytecode injects the raw request value as a String with no converter support. A non-String annotated parameter aborts the build with this IllegalArgumentException.","triggerScenarios":"A resource class constructor parameter is annotated with exactly one of @QueryParam/@PathParam/@MatrixParam/@CookieParam but its declared type is not String (e.g. int, Long, UUID). Hit during Quarkus build in CustomResourceProducersGenerator.generate().","commonSituations":"Declaring typed constructor params out of habit from field/method injection where automatic conversion to int/long works; expecting ParamConverter support which is intentionally not implemented here (see the TODO in the source).","solutions":["Change the constructor parameter type to String and convert it manually inside the constructor","Move the parameter to the resource method signature where automatic type conversion is supported","Use field injection on a @RequestScoped resource instead of constructor injection"],"exampleFix":"// before\npublic MyResource(@PathParam(\"id\") Long id) { ... }\n// after\npublic MyResource(@PathParam(\"id\") String id) { this.id = Long.valueOf(id); }","handlingStrategy":"validation","validationCode":"// ensure annotated constructor params are String\nfor (Parameter p : ctor.getParameters()) {\n    boolean hasJaxrs = Arrays.stream(p.getAnnotations()).anyMatch(a ->\n            a.annotationType().getName().startsWith(\"jakarta.ws.rs.\"));\n    if (hasJaxrs && p.getType() != String.class)\n        throw new IllegalStateException(\"Constructor param \" + p.getName() + \" must be String\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use String for JAX-RS-annotated constructor parameters; convert manually","Use method parameters for automatic type conversion (int, long, etc.)","Do not expect ParamConverter support in resource constructors"],"tags":["jax-rs","resteasy-reactive","quarkus","type-conversion","constructor-injection"],"backgroundTag":"constructor-param-type-mismatch","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"}