apache/flink · error · InvalidTypesException

Type information extraction for tuples (except Tuple0) canno

Error message

Type information extraction for tuples (except Tuple0) cannot be done based on the class.

What it means

Thrown by TypeExtractor.privateGetForClass when a class is a subclass of org.apache.flink.api.java.tuple.Tuple (Tuple1–Tuple25) but is not Tuple0. Flink cannot extract type information for tuples (except Tuple0) based on the raw class alone, because tuple field types are only recoverable from generic type arguments, not from the class itself.

Source

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

        // check for SQL time types
        TypeInformation<OUT> timeTypeInfo = SqlTimeTypeInfo.getInfoFor(clazz);
        if (timeTypeInfo != null) {
            return timeTypeInfo;
        }

        // check for subclasses of Value
        if (Value.class.isAssignableFrom(clazz)) {
            Class<? extends Value> valueClass = clazz.asSubclass(Value.class);
            return (TypeInformation<OUT>) ValueTypeInfo.getValueTypeInfo(valueClass);
        }

        // check for subclasses of Tuple
        if (Tuple.class.isAssignableFrom(clazz)) {
            if (clazz == Tuple0.class) {
                return new TupleTypeInfo(Tuple0.class);
            }
            throw new InvalidTypesException(
                    "Type information extraction for tuples (except Tuple0) cannot be done based on the class.");
        }

        // check for Enums
        if (Enum.class.isAssignableFrom(clazz)) {
            return new EnumTypeInfo(clazz);
        }

        // check for Variant
        if (Variant.class.isAssignableFrom(clazz)) {
            return (TypeInformation<OUT>) VariantTypeInfo.INSTANCE;
        }

        // check for Bitmap
        if (Bitmap.class.isAssignableFrom(clazz)) {
            return (TypeInformation<OUT>) BitmapTypeInfo.INSTANCE;
        }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Provide generic type arguments by using a TypeHint: TypeInformation.of(new TypeHint<Tuple2<String, Integer>>(){}).
  2. Use .returns(TypeInformation.of(new TypeHint<Tuple2<String,Integer>>(){})) on the UDF.
  3. Create a concrete subclass of Tuple with fixed field types for the type extractor to work with.
  4. If using Tuple0, the extraction succeeds automatically; for other tuples always supply type arguments.

Example fix

// before
TypeInformation<Tuple2> info = TypeExtractor.createTypeInfo(Tuple2.class);
// throws: cannot extract tuple type from raw class

// after
TypeInformation<Tuple2<String, Integer>> info =
    TypeInformation.of(new TypeHint<Tuple2<String, Integer>>(){});
Defensive patterns

Strategy: validation

Validate before calling

// Before calling createTypeInfo with a Tuple class, check arity
if (Tuple.class.isAssignableFrom(clazz) && clazz != Tuple0.class) {
    // provide explicit type arguments via TypeHint instead
    ti = TypeInformation.of(new TypeHint<Tuple2<String,Integer>>(){});
}

Type guard

static boolean isRawTupleClass(Class<?> clazz) {
    return Tuple.class.isAssignableFrom(clazz) && clazz != Tuple0.class;
}

Try / catch

try {
    TypeInformation<?> ti = TypeExtractor.createTypeInfo(Tuple2.class);
} catch (InvalidTypesException e) {
    ti = TypeInformation.of(new TypeHint<Tuple2<String, Integer>>(){});
}

Prevention

When it happens

Trigger: Called during privateGetForClass when clazz is assignable to Tuple.class and is not Tuple0.class. This occurs when TypeExtractor.createTypeInfo is called with a Tuple subclass raw class (e.g., Tuple2.class) without generic type arguments, or when a function returns a Tuple subclass without specifying its generic field types.

Common situations: Calling TypeExtractor.createTypeInfo(Tuple2.class) directly. Using a raw Tuple class in a UDF return without generics. Creating a DataSet<Tuple> without specifying field types. Tuple types in state or broadcast variables without explicit TypeInformation.

Related errors


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