apache/flink · error · InvalidTypesException

Usage of class Tuple as a type is not allowed. Use a concret

Error message

Usage of class Tuple as a type is not allowed. Use a concrete subclass (e.g. Tuple1, Tuple2, etc.) instead.

What it means

Thrown by TypeExtractor.createTypeInfoWithTypeHierarchy when the type being analyzed is exactly Tuple.class (the abstract base class). Flink requires concrete tuple subclasses (Tuple1 through Tuple25) because the arity and field types must be known at compile time. The raw Tuple class has no fields and cannot be instantiated or serialized.

Source

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

    private <IN1, IN2, OUT> TypeInformation<OUT> createTypeInfoWithTypeHierarchy(
            List<Type> typeHierarchy,
            Type t,
            TypeInformation<IN1> in1Type,
            TypeInformation<IN2> in2Type) {

        // check if type information can be created using a type factory
        final TypeInformation<OUT> typeFromFactory =
                createTypeInfoFromFactory(t, typeHierarchy, in1Type, in2Type);
        if (typeFromFactory != null) {
            return typeFromFactory;
        }
        // check if type is a subclass of tuple
        else if (isClassType(t) && Tuple.class.isAssignableFrom(typeToClass(t))) {
            Type curT = t;

            // do not allow usage of Tuple as type
            if (typeToClass(t).equals(Tuple.class)) {
                throw new InvalidTypesException(
                        "Usage of class Tuple as a type is not allowed. Use a concrete subclass (e.g. Tuple1, Tuple2, etc.) instead.");
            }

            // go up the hierarchy until we reach immediate child of Tuple (with or without
            // generics)
            // collect the types while moving up for a later top-down
            List<Type> typeHierarchyForSubtypes = new ArrayList<>(typeHierarchy);
            while (!(isClassType(curT) && typeToClass(curT).getSuperclass().equals(Tuple.class))) {
                typeHierarchyForSubtypes.add(curT);
                curT = typeToClass(curT).getGenericSuperclass();
            }

            if (curT == Tuple0.class) {
                return new TupleTypeInfo(Tuple0.class);
            }

            // check if immediate child of Tuple has generics
            if (curT instanceof Class<?>) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Use a concrete tuple subclass: Tuple2, Tuple3, ..., Tuple25.
  2. Specify the concrete type using TypeInformation.of(new TypeHint<Tuple2<String,Integer>>(){}).
  3. If the arity is dynamic, use Row instead of Tuple.
  4. Ensure generic code propagates the concrete tuple subclass rather than erasing to Tuple.

Example fix

// before
public class MyMapper<T extends Tuple> implements MapFunction<String, T> { ... }
// after
public class MyMapper implements MapFunction<String, Tuple2<String, Integer>> {
    public Tuple2<String, Integer> map(String s) {
        return Tuple2.of(s, s.length());
    }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (type.equals(Tuple.class)) {
    throw new IllegalArgumentException(
        "Use a concrete Tuple subclass (Tuple1..Tuple25) instead of raw Tuple");
}

Type guard

static boolean isConcreteTupleType(Type t) {
    return t instanceof Class<?> && Tuple.class.isAssignableFrom((Class<?>) t)
        && !t.equals(Tuple.class);
}

Prevention

When it happens

Trigger: Using Tuple.class as a type parameter: DataSet<Tuple> instead of DataSet<Tuple2<String, Integer>>. A function returning raw Tuple. A POJO field typed as Tuple without a concrete subclass. Generic code that erases Tuple2<String,Integer> to Tuple.

Common situations: Developer writes generic utilities that use Tuple as a type bound without specifying arity. Accidentally using Tuple.class in TypeInformation.of(Tuple.class). Lambda type erasure reduces Tuple2 to raw Tuple.

Related errors


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