apache/flink · error · InvalidTypesException

Type extraction is not possible on Either type as it does no

Error message

Type extraction is not possible on Either type as it does not contain information about the 'right' type.

What it means

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.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/EitherTypeInfoFactory.java:44

import java.lang.reflect.Type;
import java.util.Map;

public class EitherTypeInfoFactory<L, R> extends TypeInfoFactory<Either<L, R>> {

    @Override
    public TypeInformation<Either<L, R>> createTypeInfo(
            Type t, Map<String, TypeInformation<?>> genericParameters) {
        TypeInformation<?> leftType = genericParameters.get("L");
        TypeInformation<?> rightType = genericParameters.get("R");

        if (leftType == null) {
            throw new InvalidTypesException(
                    "Type extraction is not possible on Either"
                            + " type as it does not contain information about the 'left' type.");
        }

        if (rightType == null) {
            throw new InvalidTypesException(
                    "Type extraction is not possible on Either"
                            + " type as it does not contain information about the 'right' type.");
        }

        return new EitherTypeInfo(leftType, rightType);
    }
}

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Supply explicit type hints via .returns(TypeInformation.of(new TypeHint<Either<L,R>>(){})).
  2. Ensure the Right type is a concrete, inferable class in the function signature.
  3. Replace Either with a tuple/POJO if both types cannot be statically known.

Example fix

// before
DataStream<Either<String,?>> out = in.map(this::classify); // R unknown

// after
DataStream<Either<String,Integer>> out = in
  .map(this::classify)
  .returns(TypeInformation.of(new TypeHint<Either<String,Integer>>(){}));
Defensive patterns

Strategy: validation

Validate before calling

TypeInformation<Either<L, R>> ti =
    TypeInformation.of(new TypeHint<Either<L, R>>(){});

Type guard

static <L,R> TypeInformation<Either<L,R>> eitherTi(Class<L> l, Class<R> r) {
    return new EitherTypeInfo<>(TypeInformation.of(l), TypeInformation.of(r));
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/8967daff5b5e5bae. Report an issue: GitHub.