quarkusio/quarkus · error · IllegalArgumentException

Type has no raw type class:

Error message

Type has no raw type class: 

What it means

ReflectUtil.rawTypeOf extracts the raw Class behind a java.lang.reflect Type. Only Class, ParameterizedType and GenericArrayType have a raw type; if the Type is anything else (TypeVariable, WildcardType) it throws this IllegalArgumentException. It typically appears when reflection-based code receives an unresolved generic type where a concrete type was expected.

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/util/ReflectUtil.java:77

    public static boolean isOptionalOf(Type type, Class<?> nestedType) {
        return isThingOf(type, Optional.class, nestedType);
    }

    public static boolean isThingOf(Type type, Class<?> thing, Class<?> nestedType) {
        return type instanceof ParameterizedType && rawTypeIs(type, thing)
                && rawTypeExtends(typeOfParameter(type, 0), nestedType);
    }

    public static Class<?> rawTypeOf(final Type type) {
        if (type instanceof Class<?>) {
            return (Class<?>) type;
        } else if (type instanceof ParameterizedType) {
            return rawTypeOf(((ParameterizedType) type).getRawType());
        } else if (type instanceof GenericArrayType) {
            return Array.newInstance(rawTypeOf(((GenericArrayType) type).getGenericComponentType()), 0).getClass();
        } else {
            throw new IllegalArgumentException("Type has no raw type class: " + type);
        }
    }

    private static final Class<?>[] NO_CLASSES = new Class[0];

    public static Class<?>[] rawTypesOfDestructive(final Type[] types) {
        if (types.length == 0) {
            return NO_CLASSES;
        }
        Type t;
        Class<?> r;
        for (int i = 0; i < types.length; i++) {
            t = types[i];
            r = rawTypeOf(t);
            if (r != t) {
                types[i] = r;
            }
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Provide the type argument so the reflective type is parameterized: use anonymous subclassing or TypeLiteral to capture generics (new TypeLiteral<List<String>>() {}).
  2. Ensure the reflected member is accessed from a concrete (non-raw) class.
  3. Check that generics aren't lost through an intermediate raw-typed variable or erasure at the call site.
  4. If you cannot guarantee resolution, pre-check with instanceof ParameterizedType / Class before calling rawTypeOf.

Example fix

// before
Foo<String> f = (Foo<String>) new Foo(); // raw -> TypeVariable leaks
// after
Foo<String> f = new Foo<>() {} or use TypeLiteral: new TypeLiteral<Foo<String>>() {}
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean hasRawType(java.lang.reflect.Type t) {
    return t instanceof Class || t instanceof ParameterizedType || t instanceof GenericArrayType;
}

Type guard

boolean resolvable = !(type instanceof TypeVariable || type instanceof WildcardType);

Try / catch

try { Class<?> raw = ReflectUtil.rawTypeOf(type); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Type has no raw type class")) { /* type is TypeVariable/Wildcard: resolve generics first */ } else throw e; }

Prevention

When it happens

Trigger: Calling rawTypeOf/rawTypeOfParameter/rawTypesOfDestructive with a Type that is a TypeVariable or WildcardType — e.g. obtaining a generic return/field type from an unparameterized generic class (getClass() on new Foo<T>() or a raw-typed reference).

Common situations: Instantiating a generic class without a type argument (new AsyncBuilder() instead of new AsyncBuilder<String>()), reading generic method return types via reflection on raw classes, integrating with Quarkus utilities expecting fully-resolved types (e.g. reactive config/REST client type resolution).

Related errors


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