apache/flink · error · IllegalArgumentException

The positions and types must be of the same length

Error message

The positions and types must be of the same length

What it means

Thrown by the static helper checkAndCoSort(int[] positions, Class<?>[] types) when the positions array and the types array have different lengths. The method co-sorts both arrays by position, so they must be parallel arrays of equal length. This is a programming-error guard, not a data-quality check.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/io/GenericCsvInputFormat.java:530

            // field is not quoted
            while (i < delimLimit && !FieldParser.delimiterNext(bytes, i, delim)) {
                i++;
            }

            if (i >= delimLimit) {
                // no delimiter found. We are at the end of the record
                return limit;
            } else {
                // delimiter found.
                return i + delim.length;
            }
        }
    }

    @SuppressWarnings("unused")
    protected static void checkAndCoSort(int[] positions, Class<?>[] types) {
        if (positions.length != types.length) {
            throw new IllegalArgumentException(
                    "The positions and types must be of the same length");
        }

        TreeMap<Integer, Class<?>> map = new TreeMap<Integer, Class<?>>();

        for (int i = 0; i < positions.length; i++) {
            if (positions[i] < 0) {
                throw new IllegalArgumentException(
                        "The field " + " (" + positions[i] + ") is invalid.");
            }
            if (types[i] == null) {
                throw new IllegalArgumentException("The type " + i + " is invalid (null)");
            }

            if (map.containsKey(positions[i])) {
                throw new IllegalArgumentException(
                        "The position " + positions[i] + " occurs multiple times.");
            }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Ensure positions.length == types.length before calling checkAndCoSort; build both arrays from a single source of truth (e.g. a list of (index, type) pairs).
  2. Add an assertion/unit test that the two arrays are the same length.
  3. Pass a single ordered structure (List<Map.Entry<Integer,Class<?>>> or a small record) and split into the two arrays in one place.

Example fix

// before
checkAndCoSort(new int[]{0,2,4}, new Class<?>[]{Integer.class, String.class});
// after
checkAndCoSort(new int[]{0,2,4}, new Class<?>[]{Integer.class, String.class, Double.class});
Defensive patterns

Strategy: validation

Validate before calling

private static void assertParallel(int[] positions, Class<?>[] types) {
    if (positions.length != types.length) {
        throw new IllegalArgumentException(
            "positions.length (" + positions.length + ") != types.length (" + types.length + ")");
    }
}
// call before checkAndCoSort

Type guard

// Bundle index+type so they cannot diverge
record Col(int index, Class<?> type) {}
List<Col> cols = List.of(new Col(0, Integer.class), new Col(2, String.class));
int[] positions = cols.stream().mapToInt(Col::index).toArray();
Class<?>[] types = cols.stream().map(Col::type).toArray(Class<?>[]::new);

Try / catch

try {
    GenericCsvInputFormat.checkAndCoSort(positions, types);
} catch (IllegalArgumentException e) {
    throw new IllegalArgumentException("positions/types length mismatch in CSV config", e);
}

Prevention

When it happens

Trigger: A subclass of GenericCsvInputFormat (or custom input format) calls checkAndCoSort with mismatched-length positions and types arrays, e.g. positions = {0,2,4} but types = {Integer.class, String.class}.

Common situations: Hand-constructed parallel arrays in a custom CSV subclass where one array was edited but not the other; refactor that added a column to one array only; copy-paste from another format with a different arity.

Related errors


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