{"record":{"id":"d8b839bf9b50f259","repo":"apache/flink","slug":"tuple-position-is-out-of-range-f","errorCode":null,"errorMessage":"Tuple position is out of range: {f}","messagePattern":"Tuple position is out of range: (.+?)","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java","lineNumber":504,"sourceCode":"\n    // --------------------------------------------------------------------------------------------\n    //  Utilities\n    // --------------------------------------------------------------------------------------------\n\n    private static int[] createIncrIntArray(int numKeys) {\n        int[] keyFields = new int[numKeys];\n        for (int i = 0; i < numKeys; i++) {\n            keyFields[i] = i;\n        }\n        return keyFields;\n    }\n\n    @VisibleForTesting\n    static void rangeCheckFields(int[] fields, int maxAllowedField) {\n\n        for (int f : fields) {\n            if (f < 0 || f > maxAllowedField) {\n                throw new IndexOutOfBoundsException(\"Tuple position is out of range: \" + f);\n            }\n        }\n    }\n\n    public static class IncompatibleKeysException extends Exception {\n        private static final long serialVersionUID = 1L;\n        public static final String SIZE_MISMATCH_MESSAGE =\n                \"The number of specified keys is different.\";\n\n        public IncompatibleKeysException(String message) {\n            super(message);\n        }\n\n        public IncompatibleKeysException(\n                TypeInformation<?> typeInformation, TypeInformation<?> typeInformation2) {\n            super(typeInformation + \" and \" + typeInformation2 + \" are not compatible\");\n        }\n    }","sourceCodeStart":486,"sourceCodeEnd":522,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java#L486-L522","documentation":"Thrown by Keys.rangeCheckFields as an IndexOutOfBoundsException when a field index in the supplied positions array is negative or exceeds maxAllowedField (typically arity-1). This validates positional key arrays for tuple types before they are committed.","triggerScenarios":"Constructing ExpressionKeys(new int[]{0, 99}, tupleTypeInfo) where 99 exceeds the tuple arity. Passing an int[] with a negative value to keyBy or grouping APIs.","commonSituations":"Building key position arrays from external config or user input without bounds checking. Off-by-one when maxAllowedField is computed as arity-1 but caller uses arity.","solutions":["Validate each element of the positions array against [0, arity-1] before constructing ExpressionKeys.","Derive positions from type.getFieldNames() or type.getArity() rather than hardcoding.","Guard against negative values from untrusted input."],"exampleFix":"// before\nint[] positions = {0, 5};\nnew Keys.ExpressionKeys(positions, tupleTypeInfo);  // arity 3 → 5 out of range\n\n// after\nint[] positions = {0, 5};\nfor (int p : positions) {\n    if (p < 0 || p >= tupleTypeInfo.getArity()) {\n        throw new IllegalArgumentException(\"bad position \" + p);\n    }\n}\nnew Keys.ExpressionKeys(positions, tupleTypeInfo);","handlingStrategy":"validation","validationCode":"int maxAllowed = type.getArity() - 1;\nfor (int f : fields) {\n    if (f < 0 || f > maxAllowed) {\n        throw new IllegalArgumentException(\n            \"Field \" + f + \" out of range [0,\" + maxAllowed + \"]\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    Keys.rangeCheckFields(positions, arity - 1);\n} catch (IndexOutOfBoundsException e) {\n    throw new IllegalArgumentException(\"Invalid key positions\", e);\n}","preventionTips":["Bounds-check position arrays against arity-1 before constructing ExpressionKeys.","Derive positions from getArity()/getFieldNames() rather than hardcoding.","Reject negative positions from untrusted input."],"tags":["keys","index-out-of-bounds","validation","tuple","flink-core"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}