{"record":{"id":"c44fece91928214f","repo":"apache/flink","slug":"enum-type-expected","errorCode":null,"errorMessage":"Enum type expected.","messagePattern":"Enum type expected\\.","errorType":"validation","errorClass":"InvalidTypesException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java","lineNumber":1684,"sourceCode":"            }\n            // check for POJO\n            else if (typeInfo instanceof PojoTypeInfo) {\n                Class<?> clazz = null;\n                if (!(isClassType(type)\n                        && ((PojoTypeInfo<?>) typeInfo).getTypeClass()\n                                == (clazz = typeToClass(type)))) {\n                    throw new InvalidTypesException(\n                            \"POJO type '\"\n                                    + ((PojoTypeInfo<?>) typeInfo).getTypeClass().getCanonicalName()\n                                    + \"' expected but was '\"\n                                    + clazz.getCanonicalName()\n                                    + \"'.\");\n                }\n            }\n            // check for Enum\n            else if (typeInfo instanceof EnumTypeInfo) {\n                if (!(type instanceof Class<?> && Enum.class.isAssignableFrom((Class<?>) type))) {\n                    throw new InvalidTypesException(\"Enum type expected.\");\n                }\n                // check enum type contents\n                if (!(typeInfo.getTypeClass() == type)) {\n                    throw new InvalidTypesException(\n                            \"Enum type '\"\n                                    + typeInfo.getTypeClass().getCanonicalName()\n                                    + \"' expected but was '\"\n                                    + typeToClass(type).getCanonicalName()\n                                    + \"'.\");\n                }\n            }\n            // check for generic object\n            else if (typeInfo instanceof GenericTypeInfo<?>) {\n                Class<?> clazz = null;\n                if (!(isClassType(type)\n                        && (clazz = typeToClass(type))\n                                .isAssignableFrom(\n                                        ((GenericTypeInfo<?>) typeInfo).getTypeClass()))) {","sourceCodeStart":1666,"sourceCodeEnd":1702,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java#L1666-L1702","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\npublic String map(MyRecord r) { return status.name(); }\n.returns(TypeInformation.of(MyEnum.class))\n// after\npublic MyEnum map(MyRecord r) { return record.getStatus(); }\n// returns hint matches actual type","handlingStrategy":"validation","validationCode":"// Verify the type is an Enum before extraction\nClass<?> clazz = typeToClass(type);\nif (!(clazz != null && Enum.class.isAssignableFrom(clazz))) {\n    // not an enum; use appropriate TypeInformation\n    ti = TypeInformation.of(clazz);\n}","typeGuard":"static boolean isEnumType(Type t) {\n    return t instanceof Class<?> && Enum.class.isAssignableFrom((Class<?>) t);\n}","tryCatchPattern":"try {\n    TypeInformation<?> ti = TypeExtractor.createTypeInfo(myFunction.getClass());\n} catch (InvalidTypesException e) {\n    ti = TypeInformation.of(MyEnum.class);\n}","preventionTips":["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."],"tags":["type-extraction","enum","typeinfo","udf"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}