{"record":{"id":"c65c097e16bb061c","repo":"quarkusio/quarkus","slug":"unsupported-param-type-paramtype","errorCode":null,"errorMessage":"Unsupported param type: \" + paramType","messagePattern":"Unsupported param type: \" \\+ paramType","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/reactive-routes/deployment/src/main/java/io/quarkus/vertx/web/deployment/ReactiveRoutesProcessor.java","lineNumber":1736,"sourceCode":"                tc.body(b2 -> {\n                    if (paramType.name().equals(DotName.BOOLEAN_CLASS_NAME)) {\n                        b2.set(param, b2.invokeStatic(Methods.BOOLEAN_VALUE_OF, param));\n                    } else if (paramType.name().equals(DotName.BYTE_CLASS_NAME)) {\n                        b2.set(param, b2.invokeStatic(Methods.BYTE_VALUE_OF, param));\n                    } else if (paramType.name().equals(DotName.SHORT_CLASS_NAME)) {\n                        b2.set(param, b2.invokeStatic(Methods.SHORT_VALUE_OF, param));\n                    } else if (paramType.name().equals(DotName.INTEGER_CLASS_NAME)) {\n                        b2.set(param, b2.invokeStatic(Methods.INTEGER_VALUE_OF, param));\n                    } else if (paramType.name().equals(DotName.LONG_CLASS_NAME)) {\n                        b2.set(param, b2.invokeStatic(Methods.LONG_VALUE_OF, param));\n                    } else if (paramType.name().equals(DotName.FLOAT_CLASS_NAME)) {\n                        b2.set(param, b2.invokeStatic(Methods.FLOAT_VALUE_OF, param));\n                    } else if (paramType.name().equals(DotName.DOUBLE_CLASS_NAME)) {\n                        b2.set(param, b2.invokeStatic(Methods.DOUBLE_VALUE_OF, param));\n                    } else if (paramType.name().equals(DotName.CHARACTER_CLASS_NAME)) {\n                        b2.set(param, b2.invokeStatic(Methods.CHARACTER_VALUE_OF, b2.withString(param).charAt(0)));\n                    } else {\n                        throw new IllegalArgumentException(\"Unsupported param type: \" + paramType);\n                    }\n                });\n                tc.catch_(Throwable.class, \"e\", (b2, e) -> {\n                    b2.throw_(b2.new_(ConstructorDesc.of(IllegalArgumentException.class, String.class, Throwable.class),\n                            Const.of(\"Error converting parameter #\" + methodParam.position() + \" of method \"\n                                    + methodParam.method().declaringClass() + \".\" + methodParam.method().name() + \"()\"),\n                            e));\n                });\n            });\n        });\n\n    }\n\n    @FunctionalInterface\n    interface ValueProvider {\n        Expr get(MethodParameterInfo methodParam, Set<AnnotationInstance> annotations, Var routingContext,\n                BlockCreator bc, BuildProducer<ReflectiveHierarchyBuildItem> reflectiveHierarchy);\n","sourceCodeStart":1718,"sourceCodeEnd":1754,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/reactive-routes/deployment/src/main/java/io/quarkus/vertx/web/deployment/ReactiveRoutesProcessor.java#L1718-L1754","documentation":"During build-time bytecode generation, the Quarkus reactive-routes extension generates route handler code that converts String request parameters into the method's declared parameter types (Integer, Long, Float, Double, Character, etc.). If a route method declares a parameter whose type has no conversion recipe, the generated bytecode factory throws IllegalArgumentException at build time.","triggerScenarios":"Declaring a @Route-annotated method with a @Param (query/path parameter) whose type is not one of the supported boxed primitives (e.g. a LocalDate, UUID, BigDecimal, or custom POJO parameter).","commonSituations":"Migrating an app to reactive routes and reusing DTO types for parameters; assuming automatic conversion for date/time or numeric wrapper types like BigInteger; copying a controller from Spring where richer parameter binding exists.","solutions":["Change the route method parameter to a supported type (String, Integer, Long, Float, Double, Character, boolean/Boolean primitives) and convert manually inside the method.","Accept the parameter as String and parse it in the method body (e.g. LocalDate.parse(param)).","Register a custom converter or wrap the value in a class the extension supports; check the reactive-routes documentation for the current list of supported param types."],"exampleFix":"// before\n@Route(path = \"/by-date\", methods = HttpMethod.GET)\npublic Uni<String> byDate(@Param(\"d\") LocalDate d) { ... }\n// after\n@Route(path = \"/by-date\", methods = HttpMethod.GET)\npublic Uni<String> byDate(@Param(\"d\") String d) {\n    LocalDate date = LocalDate.parse(d);\n    ...\n}","handlingStrategy":"validation","validationCode":"private static final Set<String> SUPPORTED = Set.of(\"java.lang.String\",\"java.lang.Integer\",\"java.lang.Long\",\"java.lang.Float\",\"java.lang.Double\",\"java.lang.Character\",\"java.lang.Boolean\");\nvoid checkParamTypes(Class<?>[] types) {\n    for (Class<?> t : types)\n        if (!SUPPORTED.contains(t.getName()))\n            throw new IllegalArgumentException(\"Unsupported route param type: \" + t);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restrict route method parameters to String and boxed primitives","Parse complex types (LocalDate, UUID) inside the method body","Add an ArchUnit test asserting route param types","Check reactive-routes docs for the supported param type list before adding new endpoints"],"tags":["quarkus","reactive-routes","build-time","parameter-binding"],"backgroundTag":"unsupported-parameter-type","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"}