quarkusio/quarkus · error · RuntimeException

Failed to find Collection supertype of ${field}

Error message

Failed to find Collection supertype of ${field}

What it means

Deployment.getRuntimeParamConverter builds runtime parameter converters for injectable fields. When the field's generic type is parameterized, it tries to resolve the Collection element type via Types.findInterfaceParameterizedTypes; if the type is not a Collection or the supertype lookup returns no single type argument, the deployment fails with this RuntimeException.

Source

Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/Deployment.java:174

                field = fieldOwnerClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException | SecurityException e) {
                throw new RuntimeException(e);
            }
            Class<?> klass;
            Type genericType;
            if (single) {
                klass = field.getType();
                genericType = field.getGenericType();
            } else {
                genericType = field.getGenericType();
                if (genericType instanceof ParameterizedType) {
                    Type[] args = Types.findInterfaceParameterizedTypes(field.getType(), (ParameterizedType) genericType,
                            Collection.class);
                    if (args != null && args.length == 1) {
                        genericType = args[0];
                        klass = Types.getRawType(genericType);
                    } else {
                        throw new RuntimeException("Failed to find Collection supertype of " + field);
                    }
                } else {
                    throw new RuntimeException("Failed to find Collection supertype of " + field);
                }
            }
            Annotation[] annotations = field.getAnnotations();
            for (ResourceParamConverterProvider converterProvider : providers) {
                BeanInstance<ParamConverterProvider> instance = converterProvider.getFactory().createInstance();
                ParamConverter<?> converter = instance.getInstance().getConverter(klass, genericType, annotations);
                if (converter != null)
                    return new RuntimeParameterConverter(converter);
            }
        }
        return null;
    }

    public ThreadSetupAction getThreadSetupAction() {
        return threadSetupAction;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the field type to a concrete parameterized collection such as List<MyType> or Set<MyType>.
  2. Avoid raw Collection fields — always supply the element type parameter.
  3. If a custom collection type is required, make it implement Collection<E> with a resolvable parameterization, or inject the element collection as List instead.
  4. Use an @PathParam/@QueryParam array or provider-based conversion instead of relying on runtime converter resolution for exotic types.

Example fix

// before
@Inject CustomBag items; // non-Collection parameterized type
// after
@Inject List<MyItem> items;
Defensive patterns

Strategy: validation

Validate before calling

if (genericType instanceof ParameterizedType pt) {
    Type[] args = Types.findInterfaceParameterizedTypes(field.getType(), pt, Collection.class);
    if (args == null || args.length != 1) {
        throw new IllegalStateException("Field " + field + " must be a Collection<E> with a single type argument");
    }
}

Type guard

static boolean isConcreteCollection(java.lang.reflect.Field f) {
    return f.getGenericType() instanceof ParameterizedType pt
        && Collection.class.isAssignableFrom(f.getType())
        && pt.getActualTypeArguments().length == 1
        && !(pt.getActualTypeArguments()[0] instanceof java.lang.reflect.TypeVariable);
}

Try / catch

try {
    converter = deployment.getRuntimeParamConverter(field, ...);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Failed to find Collection supertype")) {
        throw new IllegalArgumentException("Change " + field + " to a parameterized List/Set type", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A @ConfigMap/@Context-style injectable field whose generic type is parameterized but is not a Collection (or is a Collection whose interface parameterization cannot be resolved, e.g. raw Collection or exotic custom collection types).

Common situations: Injecting into a raw Collection field; using a custom collection class that does not directly expose Collection<E> parameterization; changing a field type from List<String> to Map or another non-collection generic type.

Related errors


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