apache/flink · error · IllegalArgumentException

The type {} is invalid (null)

Error message

The type {} is invalid (null)

What it means

Thrown by checkAndCoSort when an entry in the types array is null. Each configured column position must carry a concrete Class. This usually indicates an uninitialized slot in a parallel array.

Source

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

        }
    }

    @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.");
            }

            map.put(positions[i], types[i]);
        }

        int i = 0;
        for (Map.Entry<Integer, Class<?>> entry : map.entrySet()) {
            positions[i] = entry.getKey();
            types[i] = entry.getValue();
            i++;
        }
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Fill every slot of the types array; build it from a non-null source structure.
  2. Validate types[i] != null for all i before calling checkAndCoSort.
  3. Prefer a List<Class<?>> that you only add non-null entries to, then toArray.

Example fix

// before
Class<?>[] types = new Class<?>[3];
types[0] = Integer.class; types[2] = String.class; // types[1] stays null
checkAndCoSort(positions, types);
// after
Class<?>[] types = new Class<?>[3];
types[0] = Integer.class; types[1] = String.class; types[2] = Double.class;
checkAndCoSort(positions, types);
Defensive patterns

Strategy: validation

Validate before calling

for (Class<?> t : types) {
    if (t == null) throw new IllegalArgumentException("Null type in CSV types array");
}
checkAndCoSort(positions, types);

Type guard

// Build types only from non-null entries
List<Class<?>> types = new ArrayList<>();
for (Class<?> t : rawTypes) { if (t != null) types.add(t); }

Try / catch

try {
    checkAndCoSort(positions, types);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("invalid (null)")) {
        throw new IllegalArgumentException("A CSV column type is null: " + Arrays.toString(types), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A subclass passes a types array where one element is null, e.g. types = {Integer.class, null, String.class}. Because positions and types are parallel, a null type has no parser to associate with its position.

Common situations: Partially initialized Class<?>[] array (default nulls); conditional filling that left a gap; refactor that removed a type assignment but kept the position; copy-paste where a slot was missed.

Related errors


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