{"record":{"id":"c118cfdd6f635aff","repo":"apache/flink","slug":"type-information-extraction-for-tuples-except-tup","errorCode":null,"errorMessage":"Type information extraction for tuples (except Tuple0) cannot be done based on the class.","messagePattern":"Type information extraction for tuples \\(except Tuple0\\) cannot be done based on the class\\.","errorType":"validation","errorClass":"InvalidTypesException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java","lineNumber":1968,"sourceCode":"\n        // check for SQL time types\n        TypeInformation<OUT> timeTypeInfo = SqlTimeTypeInfo.getInfoFor(clazz);\n        if (timeTypeInfo != null) {\n            return timeTypeInfo;\n        }\n\n        // check for subclasses of Value\n        if (Value.class.isAssignableFrom(clazz)) {\n            Class<? extends Value> valueClass = clazz.asSubclass(Value.class);\n            return (TypeInformation<OUT>) ValueTypeInfo.getValueTypeInfo(valueClass);\n        }\n\n        // check for subclasses of Tuple\n        if (Tuple.class.isAssignableFrom(clazz)) {\n            if (clazz == Tuple0.class) {\n                return new TupleTypeInfo(Tuple0.class);\n            }\n            throw new InvalidTypesException(\n                    \"Type information extraction for tuples (except Tuple0) cannot be done based on the class.\");\n        }\n\n        // check for Enums\n        if (Enum.class.isAssignableFrom(clazz)) {\n            return new EnumTypeInfo(clazz);\n        }\n\n        // check for Variant\n        if (Variant.class.isAssignableFrom(clazz)) {\n            return (TypeInformation<OUT>) VariantTypeInfo.INSTANCE;\n        }\n\n        // check for Bitmap\n        if (Bitmap.class.isAssignableFrom(clazz)) {\n            return (TypeInformation<OUT>) BitmapTypeInfo.INSTANCE;\n        }\n","sourceCodeStart":1950,"sourceCodeEnd":1986,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java#L1950-L1986","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide generic type arguments by using a TypeHint: TypeInformation.of(new TypeHint<Tuple2<String, Integer>>(){}).","Use .returns(TypeInformation.of(new TypeHint<Tuple2<String,Integer>>(){})) on the UDF.","Create a concrete subclass of Tuple with fixed field types for the type extractor to work with.","If using Tuple0, the extraction succeeds automatically; for other tuples always supply type arguments."],"exampleFix":"// before\nTypeInformation<Tuple2> info = TypeExtractor.createTypeInfo(Tuple2.class);\n// throws: cannot extract tuple type from raw class\n\n// after\nTypeInformation<Tuple2<String, Integer>> info =\n    TypeInformation.of(new TypeHint<Tuple2<String, Integer>>(){});","handlingStrategy":"validation","validationCode":"// Before calling createTypeInfo with a Tuple class, check arity\nif (Tuple.class.isAssignableFrom(clazz) && clazz != Tuple0.class) {\n    // provide explicit type arguments via TypeHint instead\n    ti = TypeInformation.of(new TypeHint<Tuple2<String,Integer>>(){});\n}","typeGuard":"static boolean isRawTupleClass(Class<?> clazz) {\n    return Tuple.class.isAssignableFrom(clazz) && clazz != Tuple0.class;\n}","tryCatchPattern":"try {\n    TypeInformation<?> ti = TypeExtractor.createTypeInfo(Tuple2.class);\n} catch (InvalidTypesException e) {\n    ti = TypeInformation.of(new TypeHint<Tuple2<String, Integer>>(){});\n}","preventionTips":["Never call TypeExtractor.createTypeInfo with a raw Tuple class (except Tuple0).","Always supply generic type arguments via TypeHint for tuples.","Use .returns(TypeInformation.of(new TypeHint<TupleN<...>>(){})) on UDFs returning tuples."],"tags":["type-extraction","tuple","generic-types","typeinfo"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}