{"record":{"id":"8967daff5b5e5bae","repo":"apache/flink","slug":"type-extraction-is-not-possible-on-either-type-as-8967da","errorCode":null,"errorMessage":"Type extraction is not possible on Either type as it does not contain information about the 'right' type.","messagePattern":"Type extraction is not possible on Either type as it does not contain information about the 'right' type\\.","errorType":"exception","errorClass":"InvalidTypesException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/EitherTypeInfoFactory.java","lineNumber":44,"sourceCode":"import java.lang.reflect.Type;\nimport java.util.Map;\n\npublic class EitherTypeInfoFactory<L, R> extends TypeInfoFactory<Either<L, R>> {\n\n    @Override\n    public TypeInformation<Either<L, R>> createTypeInfo(\n            Type t, Map<String, TypeInformation<?>> genericParameters) {\n        TypeInformation<?> leftType = genericParameters.get(\"L\");\n        TypeInformation<?> rightType = genericParameters.get(\"R\");\n\n        if (leftType == null) {\n            throw new InvalidTypesException(\n                    \"Type extraction is not possible on Either\"\n                            + \" type as it does not contain information about the 'left' type.\");\n        }\n\n        if (rightType == null) {\n            throw new InvalidTypesException(\n                    \"Type extraction is not possible on Either\"\n                            + \" type as it does not contain information about the 'right' type.\");\n        }\n\n        return new EitherTypeInfo(leftType, rightType);\n    }\n}\n","sourceCodeStart":26,"sourceCodeEnd":52,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/EitherTypeInfoFactory.java#L26-L52","documentation":"Thrown by EitherTypeInfoFactory.createTypeInfo() when the 'R' (Right type) of Either<L,R> could not be resolved during type extraction. Mirror of the 'L' case: if either side is missing the factory aborts to avoid an unsound type information.","triggerScenarios":"Using Either<L,R> with an inferable left but an erased/unknown right type; the Right branch is never used concretely so the extractor cannot bind R.","commonSituations":"A function returns Either but only one side is referenced concretely; subclassing or raw usage of Either; type erasure in a generic wrapper around Either.","solutions":["Supply explicit type hints via .returns(TypeInformation.of(new TypeHint<Either<L,R>>(){})).","Ensure the Right type is a concrete, inferable class in the function signature.","Replace Either with a tuple/POJO if both types cannot be statically known."],"exampleFix":"// before\nDataStream<Either<String,?>> out = in.map(this::classify); // R unknown\n\n// after\nDataStream<Either<String,Integer>> out = in\n  .map(this::classify)\n  .returns(TypeInformation.of(new TypeHint<Either<String,Integer>>(){}));","handlingStrategy":"validation","validationCode":"TypeInformation<Either<L, R>> ti =\n    TypeInformation.of(new TypeHint<Either<L, R>>(){});","typeGuard":"static <L,R> TypeInformation<Either<L,R>> eitherTi(Class<L> l, Class<R> r) {\n    return new EitherTypeInfo<>(TypeInformation.of(l), TypeInformation.of(r));\n}","tryCatchPattern":null,"preventionTips":["Concretize both Either type parameters.","Add a Returns hint for lambdas returning Either.","Prefer a typed named function class over anonymous ones."],"tags":["type-extraction","either","generics","type-info"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}