apache/flink · error · IllegalArgumentException
Cannot convert type to class
Error message
Cannot convert type to class
What it means
Thrown by TypeExtractionUtils.typeToClass when the given Type is neither a Class nor a ParameterizedType. This covers TypeVariable (unresolved generic type variables like T), GenericArrayType, or WildcardType. The method only knows how to extract a raw Class from Class or ParameterizedType; all other Type subtypes are rejected.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractionUtils.java:285
public static List<Method> getAllDeclaredMethods(Class<?> clazz) {
List<Method> result = new ArrayList<>();
while (clazz != null) {
Method[] methods = clazz.getDeclaredMethods();
Collections.addAll(result, methods);
clazz = clazz.getSuperclass();
}
return result;
}
/** Convert ParameterizedType or Class to a Class. */
@SuppressWarnings("unchecked")
public static <T> Class<T> typeToClass(Type t) {
if (t instanceof Class) {
return (Class<T>) t;
} else if (t instanceof ParameterizedType) {
return ((Class<T>) ((ParameterizedType) t).getRawType());
}
throw new IllegalArgumentException("Cannot convert type to class");
}
/**
* Checks if a type can be converted to a Class. This is true for ParameterizedType and Class.
*/
public static boolean isClassType(Type t) {
return t instanceof Class<?> || t instanceof ParameterizedType;
}
/** Checks whether two types are type variables describing the same. */
public static boolean sameTypeVars(Type t1, Type t2) {
return t1 instanceof TypeVariable
&& t2 instanceof TypeVariable
&& ((TypeVariable<?>) t1).getName().equals(((TypeVariable<?>) t2).getName())
&& ((TypeVariable<?>) t1)
.getGenericDeclaration()
.equals(((TypeVariable<?>) t2).getGenericDeclaration());
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Bind all generic type parameters to concrete types (e.g. class MyMapper implements MapFunction<String, Integer>).
- Use an anonymous class with explicit type arguments.
- Specify the type information explicitly with .returns(TypeInformation.of(...)).
- Implement ResultTypeQueryable to bypass automatic extraction.
Example fix
// before
public class MyMapper<T> implements MapFunction<T, String> {
public String map(T value) { return value.toString(); }
}
// after
public class MyMapper implements MapFunction<String, String> {
public String map(String value) { return value.toUpperCase(); }
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!(t instanceof Class) && !(t instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Cannot convert type " + t + " to Class; must be Class or ParameterizedType");
} Type guard
static boolean isClassType(Type t) {
return t instanceof Class<?> || t instanceof ParameterizedType;
} Prevention
- Bind all generic type variables to concrete types in function classes.
- Use anonymous classes with explicit generics instead of raw type variables.
- Implement ResultTypeQueryable when generics cannot be resolved.
When it happens
Trigger: Type extraction encounters an unresolved TypeVariable (T) because the generic was never bound to a concrete type through the hierarchy. A GenericArrayType (T[]) is passed where a simple type was expected. The type hierarchy has a gap where a type variable is not resolved.
Common situations: Function generics not fully resolved (e.g. class MyMapper<T> implements MapFunction<T, String> where T is never bound). Using arrays of generic types. Deep generic inheritance chains where type variables are not resolved at some level.
Related errors
- Tuple needs to be parameterized by using generics.
- Type of TypeVariable '{}' in '{}' could not be determined. T
- The types of the interface {} could not be inferred. Support
- Type extraction is not possible on Either type as it does no
- Type extraction is not possible on Either type as it does no
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/38a0e5ec00e9aae0.
Report an issue: GitHub.