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 'left' type.

What it means

Thrown by EitherTypeInfoFactory.createTypeInfo() when the generic parameter 'L' (the Left type of Either<L,R>) was not resolved during type extraction. Either carries two type parameters; if Flink cannot infer the left one (because the type information was erased or never supplied), the factory refuses to produce a bogus EitherTypeInfo.

Source

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

import org.apache.flink.api.common.functions.InvalidTypesException;
import org.apache.flink.api.common.typeinfo.TypeInfoFactory;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.types.Either;

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. Provide an explicit TypeInformation or Returns hint: .returns(TypeInformation.of(new TypeHint<Either<LeftT,RightT>>(){})).
  2. Avoid raw Either; always parameterize it and ensure both type arguments are concrete and inferable.
  3. Wrap the function in a named class with explicit generic signature so the extractor can read L.

Example fix

// before
DataStream<Either> out = in.map(x -> Either.Left(x)); // raw Either, L unknown

// after
DataStream<Either<String,Integer>> out = in
  .map(x -> Either.Left(x.toString()))
  .returns(TypeInformation.of(new TypeHint<Either<String,Integer>>(){}));
Defensive patterns

Strategy: validation

Validate before calling

// Ensure 'L' is inferable by providing an explicit TypeHint
TypeInformation<Either<LeftT, RightT>> ti =
    TypeInformation.of(new TypeHint<Either<LeftT, RightT>>(){});

Type guard

// Type guard: both type args present
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> as a function return type or in a TypeInformation hint without enough generic information for the extractor to bind L; annotating with @TypeInfo and letting EitherTypeInfoFactory run with a missing 'L' entry in genericParameters.

Common situations: Returning Either from a lambda whose generic type is erased; using raw Either; subclassing Either without preserving type arguments; a MapFunction<Either<X,Y>, ...> where X cannot be inferred.

Related errors


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