{"record":{"id":"6c9f33e141c89fe6","repo":"quarkusio/quarkus","slug":"could-not-create-converter-for-elementtype-for","errorCode":null,"errorMessage":"Could not create converter for ${elementType} for ${builder.getErrorLocation()} of type ${builder.getType()}","messagePattern":"Could not create converter for (.+?) for (.+?) of type (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java","lineNumber":502,"sourceCode":"\n        if (SUPPORTED_MULTIPART_FILE_TYPES.contains(DotName.createSimple(declaredType))) {\n            fileFormNames.add(name);\n        }\n        return new ServerMethodParameter(name,\n                elementType, declaredType, declaredTypes.getDeclaredUnresolvedType(),\n                type, single, signature,\n                converter, defaultValue, parameterResult.isObtainedAsCollection(), parameterResult.isOptional(), encoded,\n                parameterResult.getCustomParameterExtractor(), mimeType, parameterResult.getSeparator());\n    }\n\n    @Override\n    protected void handleOtherParam(Map<String, String> existingConverters, String errorLocation, boolean hasRuntimeConverters,\n            ServerIndexedParameter builder, String elementType, MethodInfo currentMethodInfo) {\n        try {\n            builder.setConverter(extractConverter(elementType, index,\n                    existingConverters, errorLocation, hasRuntimeConverters, builder.getAnns(), currentMethodInfo));\n        } catch (Throwable throwable) {\n            throw new RuntimeException(\"Could not create converter for \" + elementType + \" for \" + builder.getErrorLocation()\n                    + \" of type \" + builder.getType(), throwable);\n        }\n    }\n\n    @Override\n    protected void handleSortedSetParam(Map<String, String> existingConverters, String errorLocation,\n            boolean hasRuntimeConverters, ServerIndexedParameter builder, String elementType, MethodInfo currentMethodInfo) {\n        ParameterConverterSupplier converter = extractConverter(elementType, index,\n                existingConverters, errorLocation, hasRuntimeConverters, builder.getAnns(), currentMethodInfo);\n        builder.setConverter(new SortedSetConverter.SortedSetSupplier(converter));\n    }\n\n    @Override\n    protected void handleOptionalParam(Map<String, String> existingConverters,\n            Map<DotName, AnnotationInstance> parameterAnnotations,\n            String errorLocation,\n            boolean hasRuntimeConverters, ServerIndexedParameter builder, String elementType, String genericElementType,\n            MethodInfo currentMethodInfo) {","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java#L484-L520","documentation":"For simple indexed parameters (@QueryParam, @HeaderParam, etc.), handleOtherParam builds a runtime converter via extractConverter. If converter creation fails for any reason (unsupported type, no ParamConverter, no String factory), the Throwable is wrapped in this RuntimeException naming the element type, error location, and parameter type.","triggerScenarios":"Declaring @QueryParam(\"ids\") List<SomePojo> ids, or a raw/custom type with no registered ParamConverter and no valueOf/of/fromString(String) factory.","commonSituations":"Using entity/DTO classes as query/header params; custom types that worked under classic RESTEasy but lack reactive converters; enums refactored without valueOf-compatible factories.","solutions":["Change the parameter to a convertible type (String, primitive, wrapper, enum, or a type with public static valueOf/of/fromString(String)) or register a ParamConverter/ParamConverterProvider.","Inspect the wrapped cause attached to this RuntimeException — it names the exact failure.","Upgrade Quarkus if the type should be built-in supported.","Accept String and parse manually as a last resort."],"exampleFix":"// before\n@QueryParam(\"range\")\nRange range; // custom type, no converter\n\n// after\n@QueryParam(\"range\")\nString range; // parse manually, or register a ParamConverter for Range","handlingStrategy":"type-guard","validationCode":"static boolean isConvertibleParamType(Class<?> t) {\n    if (t == String.class || t.isPrimitive()) return true;\n    if (t.isEnum()) return true;\n    for (String m : new String[]{\"valueOf\", \"of\", \"from\", \"fromString\", \"parse\"}) {\n        try { t.getMethod(m, String.class); return true; } catch (NoSuchMethodException ignored) {}\n    }\n    return false;\n}","typeGuard":"static boolean hasStringFactory(Class<?> t) {\n    return java.util.Arrays.stream(t.getMethods()).anyMatch(m ->\n        java.lang.reflect.Modifier.isStatic(m.getModifiers())\n        && m.getParameterCount() == 1 && m.getParameterTypes()[0] == String.class\n        && t.isAssignableFrom(m.getReturnType()));\n}","tryCatchPattern":"try {\n    deploymentResult = quarkusBuild();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Could not create converter for\")) {\n        log.error(\"Register a ParamConverter or change the param type: \" + e.getMessage(), e.getCause());\n    } else { throw e; }\n}","preventionTips":["Use String/primitive/enum/factory-based types for @QueryParam/@HeaderParam.","Register ParamConverters for domain value types early.","Always inspect the wrapped cause for the root failure.","Run startup tests in CI."],"tags":["resteasy-reactive","quarkus","param-converter","queryparam","deployment-failure"],"backgroundTag":"param-converter-not-found","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"}