{"record":{"id":"8db2d848235b3786","repo":"apache/flink","slug":"enum-type-expected-but-was","errorCode":null,"errorMessage":"Enum type '{}' expected but was '{}'.","messagePattern":"Enum type '(.+?)' expected but was '(.+?)'\\.","errorType":"validation","errorClass":"InvalidTypesException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java","lineNumber":1688,"sourceCode":"                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()))) {\n                    throw new InvalidTypesException(\n                            \"Generic type '\"\n                                    + ((GenericTypeInfo<?>) typeInfo)\n                                            .getTypeClass()","sourceCodeStart":1670,"sourceCodeEnd":1706,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java#L1670-L1706","documentation":"Thrown by TypeExtractor.validateInfo when an EnumTypeInfo is expected, the type is an Enum, but the expected enum class differs from the actual enum class found by reflection. This indicates a mismatch between two specific enum types.","triggerScenarios":"Called during validateInfo after confirming the type is an Enum, but typeInfo.getTypeClass() != type (the actual class). Occurs when the declared EnumTypeInfo references one enum but the reflected type argument resolves to a different enum class.","commonSituations":"Generic UDFs where different enum types are used in the declared vs actual positions. Refactoring enum types (renaming/moving) without updating type hints. Using a parent or related enum type where a specific one was declared.","solutions":["Align the declared EnumTypeInfo with the actual enum class used at runtime.","Provide the correct explicit TypeInformation via .returns(TypeInformation.of(ActualEnum.class)).","Check for accidental enum substitution (e.g., StatusEnum vs ColorEnum).","Update type hints after enum refactoring."],"exampleFix":"// before\n.returns(TypeInformation.of(OldStatusEnum.class)) // actual is NewStatusEnum\n// after\n.returns(TypeInformation.of(NewStatusEnum.class))","handlingStrategy":"validation","validationCode":"// Check that the expected enum class matches the actual\nClass<?> expectedEnum = typeInfo.getTypeClass();\nClass<?> actualEnum = (Class<?>) type;\nif (expectedEnum != actualEnum) {\n    // align enum types\n    ti = TypeInformation.of(actualEnum);\n}","typeGuard":"static boolean enumClassesMatch(EnumTypeInfo<?> expected, Class<?> actual) {\n    return expected.getTypeClass() == actual;\n}","tryCatchPattern":"try {\n    validateInfo(hierarchy, type, enumTypeInfo);\n} catch (InvalidTypesException e) {\n    ti = TypeInformation.of((Class<?>) type);\n}","preventionTips":["Align declared EnumTypeInfo with the actual enum class.","Avoid substituting one enum for another in generic positions.","Update type hints after refactoring enum types."],"tags":["type-extraction","enum","type-mismatch","typeinfo"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}