{"record":{"id":"463a530007478635","repo":"quarkusio/quarkus","slug":"converter-converter-name-must-be-parameterize","errorCode":null,"errorMessage":"Converter ${converter.name()} must be parameterized with a single type","messagePattern":"Converter (.+?) must be parameterized with a single type","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java","lineNumber":1242,"sourceCode":"            return classLoader.loadClass(name);\n        } catch (ClassNotFoundException e) {\n            throw new IllegalStateException(\"The class (\" + name + \") cannot be created during deployment.\", e);\n        }\n    }\n\n    private static Type getConverterType(final ClassInfo converter, final CombinedIndexBuildItem combinedIndex) {\n        if (converter.name().toString().equals(Object.class.getName())) {\n            throw new IllegalArgumentException(\n                    \"Can not add converter \" + converter.name() + \" that is not parameterized with a type\");\n        }\n\n        for (Type type : converter.interfaceTypes()) {\n            if (type instanceof ParameterizedType) {\n                ParameterizedType parameterizedType = type.asParameterizedType();\n                if (parameterizedType.name().equals(CONVERTER_NAME)) {\n                    List<Type> arguments = parameterizedType.arguments();\n                    if (arguments.size() != 1) {\n                        throw new IllegalArgumentException(\n                                \"Converter \" + converter.name() + \" must be parameterized with a single type\");\n                    }\n                    return arguments.get(0);\n                }\n            }\n        }\n\n        return getConverterType(combinedIndex.getComputingIndex().getClassByName(converter.superName()), combinedIndex);\n    }\n}\n","sourceCodeStart":1224,"sourceCodeEnd":1253,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java#L1224-L1253","documentation":"A Converter<T> implementation must be parameterized with exactly one type argument. When the parameterized Converter interface found on the converter class has zero or more than one type argument, getConverterType throws this IllegalArgumentException.","triggerScenarios":"A converter class implements a parameterized type whose raw name equals Converter but whose type-argument list size != 1, discovered while scanning interfaceTypes in config generation.","commonSituations":"Mistakenly implementing a multi-parameter generic interface variant or copying a generic converter signature like Converter<A, B>; accidentally matching a different Converter interface name with two parameters; IDE auto-import of the wrong Converter type.","solutions":["Ensure the class implements io.smallrye.config.Converter<T> with exactly one type parameter","Verify the imported Converter is io.smallrye.config.Converter, not a same-named interface from another library","Split any two-type converter into a single-type converter plus an adapter"],"exampleFix":"// before\npublic class PairConverter implements Converter<Pair, String> { ... }\n// after\npublic class PairConverter implements Converter<Pair> { ... }","handlingStrategy":"type-guard","validationCode":"ParameterizedType pt = (ParameterizedType) ColorConverter.class.getGenericInterfaces()[0];\nif (pt.getActualTypeArguments().length != 1) {\n    throw new IllegalStateException(\"Converter must have exactly one type argument\");\n}","typeGuard":"static boolean hasSingleTypeArg(Class<?> c) {\n    return java.util.Arrays.stream(c.getGenericInterfaces())\n        .filter(t -> t instanceof ParameterizedType pt\n            && pt.getRawType().equals(io.smallrye.config.Converter.class))\n        .allMatch(t -> ((ParameterizedType) t).getActualTypeArguments().length == 1);\n}","tryCatchPattern":null,"preventionTips":["Import io.smallrye.config.Converter specifically (watch for same-named interfaces)","Keep converter signatures to a single type parameter; wrap multi-type logic in a holder class","Add a compile-time annotation processor or test asserting generic arity","Review converter signatures during code review after copy-paste"],"tags":["quarkus","config","generics","converter"],"backgroundTag":"wrong-generic-arity","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"}