apache/flink · error · InvalidTypesException
Tuple needs to be parameterized by using generics.
Error message
Tuple needs to be parameterized by using generics.
What it means
Thrown when Flink's TypeExtractor encounters a Tuple subclass that is used as a raw type without type parameters. The extractor walks the class hierarchy up to the immediate child of Tuple and checks whether that child is a ParameterizedType; if it is a plain Class instead, the generic field types of the tuple have been erased and cannot be recovered. This makes serialization and state management impossible, so extraction fails.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java:915
"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<?>) {
throw new InvalidTypesException(
"Tuple needs to be parameterized by using generics.");
}
typeHierarchyForSubtypes.add(curT);
// create the type information for the subtypes
final TypeInformation<?>[] subTypesInfo =
createSubTypesInfo(
t,
(ParameterizedType) curT,
typeHierarchyForSubtypes,
in1Type,
in2Type,
false);
// type needs to be treated a pojo due to additional fields
if (subTypesInfo == null) {
return analyzePojo(t, new ArrayList<>(typeHierarchy), in1Type, in2Type);
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Parameterize the Tuple subclass with explicit field types: `class Event extends Tuple2<String, Long> {}`
- If using the DataStream API, supply the TypeInformation explicitly via `.returns(TypeInformation.of(new TypeHint<Tuple2<String,Long>>(){}))`
- Implement ResultTypeQueryable on the function and override getProducedType() to return the TypeInformation manually
- Use a POJO or Row instead of a custom Tuple subclass when genericity is hard to express
Example fix
// before
class Event extends Tuple2 {}
// after
class Event extends Tuple2<String, Long> {
public String getId() { return f0; }
public long getTs() { return f1; }
} Defensive patterns
Strategy: validation
Validate before calling
// Before using a Tuple subclass, verify it is parameterized
Class<?> tupleClass = MyTuple.class;
Type supertype = tupleClass.getGenericSuperclass();
if (!(supertype instanceof ParameterizedType) && tupleClass != Tuple0.class) {
throw new IllegalArgumentException(
"Tuple subclass " + tupleClass.getName()
+ " must be parameterized, e.g. extends Tuple2<String, Integer>");
} Prevention
- Always specify type parameters when subclassing Tuple: `extends Tuple2<String, Long>`
- Use Flink's Tuple0 for empty tuples if needed
- Prefer POJOs or Row for complex data models to avoid Tuple parameterization issues
- Run a quick unit test calling TypeExtractor.createTypeInfo(MyClass.class) early in development
When it happens
Trigger: A subclass of Tuple (Tuple1–Tuple25) is used as a raw type — e.g. `class MyTuple extends Tuple2` without `<String,Integer>`. Occurs when a function returns or accepts a non-generic Tuple subclass, or when a Tuple subclass is defined without specifying its field types on the extends clause.
Common situations: Defining a custom Tuple subclass like `class Event extends Tuple2 {}` instead of `class Event extends Tuple2<String,Long> {}`. Using a raw Tuple subclass as a MapFunction output type. Subclassing a Tuple in legacy Java code that suppresses generics.
Related errors
- Cannot convert type to class
- The types of the interface {} could not be inferred. Support
- Parameterized Tuple type expected.
- Type extraction is not possible on Either type as it does no
- Type extraction is not possible on Either type as it does no
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/c7730c088f3e99e1.
Report an issue: GitHub.