apache/flink · error · InvalidTypesException

Type of TypeVariable '{}' in '{}' could not be determined. T

Error message

Type of TypeVariable '{}' in '{}' could not be determined. This is most likely a type erasure problem. The type extraction currently supports types with generic variables only in cases where all variables in the return type can be deduced from the input type(s). Otherwise the type has to be specified explicitly using type information.

What it means

Thrown when a function's return type is a TypeVariable (e.g. `<E>` in `class MyMapper<E> extends MapFunction<String, E>`) that could not be resolved through the type hierarchy and could not be deduced from the input type information. Java type erasure strips generic type arguments at runtime, so Flink must trace the variable through the class hierarchy and input types — if that trace fails, extraction is impossible without explicit hints.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java:965

        // type depends on another type
        // e.g. class MyMapper<E> extends MapFunction<String, E>
        else if (t instanceof TypeVariable) {
            Type typeVar = materializeTypeVariable(typeHierarchy, (TypeVariable<?>) t);

            if (!(typeVar instanceof TypeVariable)) {
                return createTypeInfoWithTypeHierarchy(typeHierarchy, typeVar, in1Type, in2Type);
            }
            // try to derive the type info of the TypeVariable from the immediate base child input
            // as a last attempt
            else {
                TypeInformation<OUT> typeInfo =
                        (TypeInformation<OUT>)
                                createTypeInfoFromInputs(
                                        (TypeVariable<?>) t, typeHierarchy, in1Type, in2Type);
                if (typeInfo != null) {
                    return typeInfo;
                } else {
                    throw new InvalidTypesException(
                            "Type of TypeVariable '"
                                    + ((TypeVariable<?>) t).getName()
                                    + "' in '"
                                    + ((TypeVariable<?>) t).getGenericDeclaration()
                                    + "' could not be determined. This is most likely a type erasure problem. "
                                    + "The type extraction currently supports types with generic variables only in cases where "
                                    + "all variables in the return type can be deduced from the input type(s). "
                                    + "Otherwise the type has to be specified explicitly using type information.");
                }
            }
        }
        // arrays with generics
        else if (t instanceof GenericArrayType) {
            GenericArrayType genericArray = (GenericArrayType) t;

            Type componentType = genericArray.getGenericComponentType();

            // due to a Java 6 bug, it is possible that the JVM classifies e.g. String[] or int[] as

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Provide the TypeInformation explicitly via `.returns(TypeInformation.of(MyOutputType.class))` on the DataStream
  2. Make the function class non-generic by binding the type variable: `class StringToLongMapper extends MapFunction<String, Long>` instead of `<E> extends MapFunction<String, E>`
  3. Implement ResultTypeQueryable and return the concrete TypeInformation from getProducedType()
  4. Use a TypeHint: `TypeInformation.of(new TypeHint<MyType>(){})`

Example fix

// before
public class JsonExtractor<T> extends MapFunction<String, T> { ... }

// after — bind the type or use .returns()
dataStream.map(new JsonExtractor<MyEvent>())
          .returns(TypeInformation.of(MyEvent.class));
Defensive patterns

Strategy: validation

Validate before calling

// Verify the function's return type is fully resolved before use
try {
    TypeInformation<?> returnInfo = TypeExtractor.createTypeInfo(
        myFunction, MapFunction.class, myFunction.getClass(), 1);
} catch (InvalidTypesException e) {
    // Provide explicit type info
    dataStream.map(myFunction).returns(TypeInformation.of(MyOutputType.class));
}

Try / catch

// Catch and provide explicit type information
try {
    resultStream = inputStream.map(myGenericFunction);
} catch (InvalidTypesException e) {
    resultStream = inputStream.map(myGenericFunction)
        .returns(TypeInformation.of(MyType.class));
}

Prevention

When it happens

Trigger: A generic function class like `class MyMapper<E> extends MapFunction<String, E>` is used without specifying E at the call site, and the input type does not carry enough information to infer E. This is the terminal failure after `materializeTypeVariable` returns an unresolved TypeVariable and `createTypeInfoFromInputs` returns null.

Common situations: Writing a reusable generic MapFunction or FlatMapFunction with an unresolved type parameter. Using lambda expressions where the return type variable cannot be traced. Subclassing a Flink function interface with an intermediate abstract generic class that does not bind the variable.

Related errors


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