apache/flink · error · InvalidTypesException
Enum type expected.
Error message
Enum type expected.
What it means
Thrown by TypeExtractor.validateInfo when an EnumTypeInfo is expected but the extracted Java type is not a Class assignable to java.lang.Enum. This means the type extractor expected an enum type but the reflected type was a regular class, a raw type, or a TypeVariable.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java:1684
}
// check for POJO
else if (typeInfo instanceof PojoTypeInfo) {
Class<?> clazz = null;
if (!(isClassType(type)
&& ((PojoTypeInfo<?>) typeInfo).getTypeClass()
== (clazz = typeToClass(type)))) {
throw new InvalidTypesException(
"POJO type '"
+ ((PojoTypeInfo<?>) typeInfo).getTypeClass().getCanonicalName()
+ "' expected but was '"
+ clazz.getCanonicalName()
+ "'.");
}
}
// check for Enum
else if (typeInfo instanceof EnumTypeInfo) {
if (!(type instanceof Class<?> && Enum.class.isAssignableFrom((Class<?>) type))) {
throw new InvalidTypesException("Enum type expected.");
}
// check enum type contents
if (!(typeInfo.getTypeClass() == type)) {
throw new InvalidTypesException(
"Enum type '"
+ typeInfo.getTypeClass().getCanonicalName()
+ "' expected but was '"
+ typeToClass(type).getCanonicalName()
+ "'.");
}
}
// check for generic object
else if (typeInfo instanceof GenericTypeInfo<?>) {
Class<?> clazz = null;
if (!(isClassType(type)
&& (clazz = typeToClass(type))
.isAssignableFrom(
((GenericTypeInfo<?>) typeInfo).getTypeClass()))) {View on GitHub (pinned to 2f3c205e92)
Solutions
- Ensure the UDF signature uses the concrete enum class (e.g., MyEnum, not T or String).
- Provide explicit TypeInformation via .returns(TypeInformation.of(MyEnum.class)).
- Avoid raw types or unbounded type variables in positions where an enum is expected.
- If the type is genuinely not an enum, use the correct TypeInformation (e.g., BasicTypeInfo.STRING_TYPE_INFO).
Example fix
// before
public String map(MyRecord r) { return status.name(); }
.returns(TypeInformation.of(MyEnum.class))
// after
public MyEnum map(MyRecord r) { return record.getStatus(); }
// returns hint matches actual type Defensive patterns
Strategy: validation
Validate before calling
// Verify the type is an Enum before extraction
Class<?> clazz = typeToClass(type);
if (!(clazz != null && Enum.class.isAssignableFrom(clazz))) {
// not an enum; use appropriate TypeInformation
ti = TypeInformation.of(clazz);
} Type guard
static boolean isEnumType(Type t) {
return t instanceof Class<?> && Enum.class.isAssignableFrom((Class<?>) t);
} Try / catch
try {
TypeInformation<?> ti = TypeExtractor.createTypeInfo(myFunction.getClass());
} catch (InvalidTypesException e) {
ti = TypeInformation.of(MyEnum.class);
} Prevention
- Use concrete enum classes in UDF signatures, not raw types or TypeVariables.
- Provide explicit .returns(TypeInformation.of(MyEnum.class)) hints.
- Avoid String substitutes for enum types.
When it happens
Trigger: Called during validateInfo when TypeInformation is an EnumTypeInfo but the reflected Type is not a Class implementing Enum.class. This occurs when a UDF declares an enum type but the generic erasure yields a non-enum class, or when an enum type is replaced by a plain class.
Common situations: Declaring a function output as an enum but using a String or other type in practice. Using raw types or TypeVariables where an enum was expected. Enum type erasure in generic function signatures.
Related errors
- Object array type expected.
- Value type expected.
- Enum type '{}' expected but was '{}'.
- POJO type '{}' expected but was '{}'.
- Generic type '{}' or a subclass of it expected but was '{}'.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/c44fece91928214f.
Report an issue: GitHub.