{"record":{"id":"4db37b8132c2ba16","repo":"quarkusio/quarkus","slug":"unsupported-field-type-for-multipart-response-mapp","errorCode":null,"errorMessage":"Unsupported field type for multipart response mapping: \" + type + \". Only classes, arrays and parameterized types are supported","messagePattern":"Unsupported field type for multipart response mapping: \" \\+ type \\+ \"\\. Only classes, arrays and parameterized types are supported","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest-client-jaxrs/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java","lineNumber":704,"sourceCode":"            String fillerClassName, ClassCreator c) {\n        MethodCreator ctor = c.getMethodCreator(MethodDescriptor.ofConstructor(fillerClassName));\n\n        ResultHandle genericType;\n        if (type.kind() == PARAMETERIZED_TYPE) {\n            genericType = createGenericTypeFromParameterizedType(ctor, type.asParameterizedType());\n        } else if (type.kind() == CLASS) {\n            genericType = ctor.newInstance(\n                    MethodDescriptor.ofConstructor(GenericType.class, java.lang.reflect.Type.class),\n                    ctor.loadClassFromTCCL(type.asClassType().name().toString()));\n        } else if (type.kind() == ARRAY) {\n            genericType = ctor.newInstance(\n                    MethodDescriptor.ofConstructor(GenericType.class, java.lang.reflect.Type.class),\n                    ctor.loadClassFromTCCL(type.asArrayType().name().toString()));\n        } else if (type.kind() == PRIMITIVE) {\n            throw new IllegalArgumentException(\"Primitive types are not supported for multipart response mapping. \" +\n                    \"Please use a wrapper class instead\");\n        } else {\n            throw new IllegalArgumentException(\"Unsupported field type for multipart response mapping: \" +\n                    type + \". Only classes, arrays and parameterized types are supported\");\n        }\n\n        ctor.invokeSpecialMethod(\n                MethodDescriptor.ofConstructor(FieldFiller.class, GenericType.class, String.class, String.class),\n                ctor.getThis(), genericType, ctor.load(partName), ctor.load(partType.value().asString()));\n        ctor.returnValue(null);\n    }\n\n    private AnnotationInstance partTypeFromGetterOrSetter(MethodInfo setter) {\n        AnnotationInstance partTypeAnno = setter.annotation(PART_TYPE_NAME);\n        if (partTypeAnno != null) {\n            return partTypeAnno;\n        }\n\n        String getterName = setter.name().replaceFirst(\"s\", \"g\");\n        MethodInfo getter = setter.declaringClass().method(getterName);\n        if (getter != null && null != (partTypeAnno = getter.annotation(PART_TYPE_NAME))) {","sourceCodeStart":686,"sourceCodeEnd":722,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest-client-jaxrs/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java#L686-L722","documentation":"The multipart response generator only supports field types that are classes, arrays, or parameterized types, because it must construct a GenericType from the Jandex Type. Any other kind (primitive was handled separately; this branch catches everything else such as type variables/unresolved kinds) is rejected with an IllegalArgumentException naming the offending type.","triggerScenarios":"Declaring a multipart response DTO field whose Jandex type kind is neither CLASS, ARRAY, nor PARAMETERIZED_TYPE — e.g. a type variable, wildcard, or void-like type — causing FieldFiller generation to fail at build time.","commonSituations":"Generic DTO classes (Wrapper<T> with an unresolved T) reused as multipart bodies; accidentally mapping a multipart response to a raw generic interface; copy-pasting fields between response and request classes.","solutions":["Replace the offending field with a concrete class, array, or parameterized type (e.g. List<String> instead of T)","Resolve generic type variables by using a concrete subclass or explicit type in the client method signature","Check the generated FieldFiller error output for the exact field type and simplify it"],"exampleFix":"// before\nclass Wrapper<T> { public T data; }\n// after\nclass Wrapper { public List<String> data; }","handlingStrategy":"validation","validationCode":"static void assertConcrete(Class<?> c) { if (c.getTypeParameters().length > 0 || c.isInterface() || c.isPrimitive()) throw new IllegalStateException(\"Multipart response type must be a concrete class: \" + c); }","typeGuard":"boolean isConcreteClass(Type t) { return t instanceof Class<?> c && !c.isInterface() && !c.isPrimitive() && !c.isArray() ? c.getTypeParameters().length == 0 : t instanceof ParameterizedType || t instanceof Class<?>; }","tryCatchPattern":"try { MultipartBody b = client.get(); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"Unsupported field type\")) { log.error(\"Simplify multipart DTO field type\"); } throw e; }","preventionTips":["Use concrete classes/parameterized types for multipart fields","Avoid type variables (T, E) in multipart DTOs","Do not share generic DTOs between JSON and multipart endpoints without concretization","Test client generation with a minimal build early"],"tags":["quarkus","rest-client","multipart","unsupported-type","build-time"],"backgroundTag":"unsupported-generic-type","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"}