{"record":{"id":"f21fede5bc492a95","repo":"quarkusio/quarkus","slug":"type-type-name-tostring-which-is-used-in","errorCode":null,"errorMessage":"Type  + type.name().toString() +  which is used in class  + declaringClass +  must define a generic argument","messagePattern":"Type  \\+ type\\.name\\(\\)\\.toString\\(\\) \\+  which is used in class  \\+ declaringClass \\+  must define a generic argument","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ConfigurationPropertiesUtil.java","lineNumber":188,"sourceCode":"            return false;\n        }\n        return !parameterizedType.arguments().get(0).name().toString().startsWith(\"java\");\n    }\n\n    private static boolean isCollection(final Type resultType) {\n        return DotNames.COLLECTION.equals(resultType.name()) ||\n                DotNames.LIST.equals(resultType.name()) ||\n                DotNames.SET.equals(resultType.name());\n    }\n\n    private static boolean isMap(final Type resultType) {\n        return DotNames.MAP.equals(resultType.name()) ||\n                DotNames.HASH_MAP.equals(resultType.name());\n    }\n\n    static Type determineSingleGenericType(Type type, DotName declaringClass) {\n        if (!(type.kind() == Type.Kind.PARAMETERIZED_TYPE)) {\n            throw new IllegalArgumentException(\"Type \" + type.name().toString() + \" which is used in class \" + declaringClass\n                    + \" must define a generic argument\");\n        }\n\n        ParameterizedType parameterizedType = type.asParameterizedType();\n        if (parameterizedType.arguments().size() != 1) {\n            throw new IllegalArgumentException(\"Type \" + type.name().toString() + \" which is used in class \" + declaringClass\n                    + \" must define a single generic argument\");\n        }\n\n        return type.asParameterizedType().arguments().get(0);\n    }\n\n    static void registerImplicitConverter(Type type, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {\n        // We need to register for reflection in case an implicit converter is required.\n        if (!MicroProfileConfigProcessor.isHandledByProducers(type)) {\n            if (type.kind() != Type.Kind.ARRAY) {\n                reflectiveClasses\n                        .produce(ReflectiveClassBuildItem.builder(type.name().toString()).methods().build());","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ConfigurationPropertiesUtil.java#L170-L206","documentation":"determineSingleGenericType extracts the single generic argument of a config property type. If the type is not a parameterized type at all (no generic argument declared), it throws IllegalArgumentException 'Type <type> which is used in class <class> must define a generic argument'. Called from the mandatory and optional value read generators for types that need one type parameter (e.g. List, Optional).","triggerScenarios":"A @ConfigurationProperties field/getter uses a generic container such as List, Set, or Optional as a raw type (Kind != PARAMETERIZED_TYPE); raised while generating config population code invoked via createReadMandatoryValueAndConvertIfNeeded / createReadOptionalValueAndConvertIfNeeded.","commonSituations":"Raw List instead of List<String>; generics omitted on an interface getter; legacy code using raw collection types.","solutions":["Add the type argument: List<String>, Optional<Duration>, etc.","Ensure interface-based config property getters declare concrete generic return types.","Avoid custom generic wrappers; only single-argument parameterized types are supported here."],"exampleFix":"// before\nList getHosts();\n\n// after\nList<String> getHosts();","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean hasSingleGenericArg(java.lang.reflect.Type t) {\n  return t instanceof java.lang.reflect.ParameterizedType pt\n      && pt.getActualTypeArguments().length == 1;\n}","tryCatchPattern":null,"preventionTips":["Never use raw List/Set/Optional in @ConfigurationProperties members","Add explicit type arguments at declaration time","Treat rawtypes compiler warnings as errors in config modules"],"tags":["quarkus","build-time","generics","raw-type"],"backgroundTag":"raw-type-missing-generics","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"}