quarkusio/quarkus · error · IllegalArgumentException

Unsupported field type for multipart response mapping: " + t

Error message

Unsupported field type for multipart response mapping: " + type + ". Only classes, arrays and parameterized types are supported

What it means

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.

Source

Thrown at extensions/resteasy-reactive/rest-client-jaxrs/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java:704

            String fillerClassName, ClassCreator c) {
        MethodCreator ctor = c.getMethodCreator(MethodDescriptor.ofConstructor(fillerClassName));

        ResultHandle genericType;
        if (type.kind() == PARAMETERIZED_TYPE) {
            genericType = createGenericTypeFromParameterizedType(ctor, type.asParameterizedType());
        } else if (type.kind() == CLASS) {
            genericType = ctor.newInstance(
                    MethodDescriptor.ofConstructor(GenericType.class, java.lang.reflect.Type.class),
                    ctor.loadClassFromTCCL(type.asClassType().name().toString()));
        } else if (type.kind() == ARRAY) {
            genericType = ctor.newInstance(
                    MethodDescriptor.ofConstructor(GenericType.class, java.lang.reflect.Type.class),
                    ctor.loadClassFromTCCL(type.asArrayType().name().toString()));
        } else if (type.kind() == PRIMITIVE) {
            throw new IllegalArgumentException("Primitive types are not supported for multipart response mapping. " +
                    "Please use a wrapper class instead");
        } else {
            throw new IllegalArgumentException("Unsupported field type for multipart response mapping: " +
                    type + ". Only classes, arrays and parameterized types are supported");
        }

        ctor.invokeSpecialMethod(
                MethodDescriptor.ofConstructor(FieldFiller.class, GenericType.class, String.class, String.class),
                ctor.getThis(), genericType, ctor.load(partName), ctor.load(partType.value().asString()));
        ctor.returnValue(null);
    }

    private AnnotationInstance partTypeFromGetterOrSetter(MethodInfo setter) {
        AnnotationInstance partTypeAnno = setter.annotation(PART_TYPE_NAME);
        if (partTypeAnno != null) {
            return partTypeAnno;
        }

        String getterName = setter.name().replaceFirst("s", "g");
        MethodInfo getter = setter.declaringClass().method(getterName);
        if (getter != null && null != (partTypeAnno = getter.annotation(PART_TYPE_NAME))) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Replace the offending field with a concrete class, array, or parameterized type (e.g. List<String> instead of T)
  2. Resolve generic type variables by using a concrete subclass or explicit type in the client method signature
  3. Check the generated FieldFiller error output for the exact field type and simplify it

Example fix

// before
class Wrapper<T> { public T data; }
// after
class Wrapper { public List<String> data; }
Defensive patterns

Strategy: validation

Validate before calling

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); }

Type guard

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<?>; }

Try / catch

try { MultipartBody b = client.get(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Unsupported field type")) { log.error("Simplify multipart DTO field type"); } throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/4db37b8132c2ba16. Report an issue: GitHub.