{"record":{"id":"44831e520ab654d5","repo":"apache/flink","slug":"pojo-type-expected-but-was-44831e","errorCode":null,"errorMessage":"POJO type '{}' expected but was '{}'.","messagePattern":"POJO 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":1673,"sourceCode":"                if (!(type instanceof Class<?> && Value.class.isAssignableFrom((Class<?>) type))) {\n                    throw new InvalidTypesException(\"Value type expected.\");\n                }\n\n                TypeInformation<?> actual;\n                // check value type contents\n                if (!typeInfo.equals(\n                        actual = ValueTypeInfo.getValueTypeInfo((Class<? extends Value>) type))) {\n                    throw new InvalidTypesException(\n                            \"Value type '\" + typeInfo + \"' expected but was '\" + actual + \"'.\");\n                }\n            }\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 '\"","sourceCodeStart":1655,"sourceCodeEnd":1691,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java#L1655-L1691","documentation":"Thrown by TypeExtractor.validateInfo when a PojoTypeInfo is expected but the reflected type's class does not exactly match the PojoTypeInfo's type class. This means the type extractor expected a specific POJO class but found a different class through reflection.","triggerScenarios":"Called during validateInfo when TypeInformation is a PojoTypeInfo and either the type is not a ClassType, or typeToClass(type) differs from the PojoInfo's getTypeClass(). Occurs when the declared POJO type class does not match the actual generic type argument resolved by reflection.","commonSituations":"Using a subclass of a POJO where the parent was expected, or vice versa. Generic functions where the POJO class is parameterized and erasure resolves to a different class. Refactoring POJO classes (renaming/moving) without updating type hints or serialized state.","solutions":["Ensure the actual runtime class matches the declared PojoTypeInfo class exactly.","Provide explicit TypeInformation via .returns(TypeInformation.of(MyPojo.class)) matching the actual class.","If using inheritance, register the correct concrete POJO class, not the parent.","Check for stale type hints after class refactoring."],"exampleFix":"// before\n.returns(TypeInformation.of(ParentPojo.class)) // but actual is ChildPojo\n// after\n.returns(TypeInformation.of(ChildPojo.class))","handlingStrategy":"validation","validationCode":"// Check POJO class match before extraction\nClass<?> expectedClass = ((PojoTypeInfo<?>) typeInfo).getTypeClass();\nClass<?> actualClass = typeToClass(type);\nif (expectedClass != actualClass) {\n    // provide correct PojoTypeInfo\n    ti = TypeInformation.of(actualClass);\n}","typeGuard":"static boolean pojoClassesMatch(TypeInformation<?> expected, Type actual) {\n    return expected instanceof PojoTypeInfo<?>\n        && isClassType(actual)\n        && ((PojoTypeInfo<?>) expected).getTypeClass() == typeToClass(actual);\n}","tryCatchPattern":"try {\n    validateInfo(hierarchy, type, pojoTypeInfo);\n} catch (InvalidTypesException e) {\n    ti = TypeInformation.of(typeToClass(type));\n}","preventionTips":["Ensure the declared POJO class exactly matches the actual class.","Provide explicit TypeInformation matching the concrete POJO class.","Update type hints after refactoring POJO classes."],"tags":["type-extraction","pojo","type-mismatch","typeinfo"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}