{"record":{"id":"90c60541fcca19f9","repo":"apache/flink","slug":"tuple-arity-expected-but-was","errorCode":null,"errorMessage":"Tuple arity '{}' expected but was '{}'.","messagePattern":"Tuple arity '(.+?)' expected but was '(.+?)'\\.","errorType":"exception","errorClass":"InvalidTypesException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java","lineNumber":1564,"sourceCode":"                    typeHierarchy.add(type);\n                    type = typeToClass(type).getGenericSuperclass();\n                }\n\n                if (type == Tuple0.class) {\n                    return;\n                }\n\n                // check if immediate child of Tuple has generics\n                if (type instanceof Class<?>) {\n                    throw new InvalidTypesException(\"Parameterized Tuple type expected.\");\n                }\n\n                TupleTypeInfo<?> tti = (TupleTypeInfo<?>) typeInfo;\n\n                Type[] subTypes = ((ParameterizedType) type).getActualTypeArguments();\n\n                if (subTypes.length != tti.getArity()) {\n                    throw new InvalidTypesException(\n                            \"Tuple arity '\"\n                                    + tti.getArity()\n                                    + \"' expected but was '\"\n                                    + subTypes.length\n                                    + \"'.\");\n                }\n\n                for (int i = 0; i < subTypes.length; i++) {\n                    validateInfo(new ArrayList<>(typeHierarchy), subTypes[i], tti.getTypeAt(i));\n                }\n            }\n            // check for primitive array\n            else if (typeInfo instanceof PrimitiveArrayTypeInfo) {\n                Type component;\n                // check if array at all\n                if (!(type instanceof Class<?>\n                                && ((Class<?>) type).isArray()\n                                && (component = ((Class<?>) type).getComponentType()) != null)","sourceCodeStart":1546,"sourceCodeEnd":1582,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java#L1546-L1582","documentation":"Thrown during input type validation for Tuple types when the number of fields in the TupleTypeInfo does not match the number of actual type arguments in the reflected ParameterizedType. For example, the stream carries TupleTypeInfo for Tuple2 (arity 2) but the function's signature declares Tuple3 (arity 3), or vice versa.","triggerScenarios":"The DataStream's TypeInformation is TupleTypeInfo with a specific arity (e.g. Tuple2, arity 2) but the function's declared input Tuple subclass has a different arity (e.g. Tuple3). The check `subTypes.length != tti.getArity()` fails.","commonSituations":"Changing the number of fields in a Tuple key or projection without updating the consuming function. Connecting a Tuple2 stream to a function expecting Tuple3. Adding or removing a field in a transformation pipeline without propagating the change.","solutions":["Match the Tuple arity in the function signature to the stream's TupleTypeInfo","If you need a different number of fields, add a map to project/reshape the Tuple","Use a POJO with named fields if the schema changes frequently"],"exampleFix":"// before — arity mismatch\nDataStream<Tuple2<String, Integer>> stream = ...;\nstream.map(new MapFunction<Tuple3<String, Integer, Long>, X>() { ... });\n\n// after — match arity\nstream.map(new MapFunction<Tuple2<String, Integer>, X>() {\n    public X map(Tuple2<String, Integer> value) { ... }\n});","handlingStrategy":"validation","validationCode":"// Verify Tuple arity matches between stream and function\nif (stream.getType() instanceof TupleTypeInfo) {\n    int streamArity = ((TupleTypeInfo<?>) stream.getType()).getArity();\n    int funcArity = getTupleArityFromFunction(myFunction); // custom helper\n    if (streamArity != funcArity) {\n        throw new IllegalStateException(\n            \"Tuple arity mismatch: stream has \" + streamArity\n            + \" fields but function expects \" + funcArity);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep Tuple arity consistent across the pipeline","Add explicit map operators when reshaping Tuple fields","Use TupleTypeInfo.getArity() to verify field counts before connecting operators","Prefer POJOs with named fields when the schema changes frequently"],"tags":["type-validation","tuple","arity-mismatch","type-mismatch","reflection"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}