apache/flink · error · IllegalArgumentException

Missing type for included field {}.

Error message

Missing type for included field {}.

What it means

Thrown by GenericCsvInputFormat.setFieldsGeneric(boolean[] includedMask, Class<?>[] fieldTypes) when the includedMask marks more fields as included than there are types supplied. Each 'true' in the mask consumes one type from fieldTypes; running out of types means a selected column has no declared type. The message names the offending field position i.

Source

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

            }
        }

        this.fieldTypes = types.toArray(new Class<?>[types.size()]);
    }

    protected void setFieldsGeneric(boolean[] includedMask, Class<?>[] fieldTypes) {
        checkNotNull(includedMask);
        checkNotNull(fieldTypes);

        ArrayList<Class<?>> types = new ArrayList<Class<?>>();

        // check if types are valid for included fields
        int typeIndex = 0;
        for (int i = 0; i < includedMask.length; i++) {

            if (includedMask[i]) {
                if (typeIndex > fieldTypes.length - 1) {
                    throw new IllegalArgumentException(
                            "Missing type for included field " + i + ".");
                }
                Class<?> type = fieldTypes[typeIndex++];

                if (type == null) {
                    throw new IllegalArgumentException(
                            "Type for included field " + i + " should not be null.");
                } else {
                    // check if we support parsers for this type
                    if (FieldParser.getParserForType(type) == null) {
                        throw new IllegalArgumentException(
                                "The type '"
                                        + type.getName()
                                        + "' is not supported for the CSV input format.");
                    }
                    types.add(type);
                }
            }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Ensure fieldTypes.length equals the number of true entries in includedMask.
  2. Build types from the mask in a single pass to keep them in sync.
  3. Add a unit assertion counting true entries against the types array length.

Example fix

// before
boolean[] mask = {true, true, true};
Class<?>[] types = {Integer.class, String.class}; // only 2 types for 3 selected
format.setFieldsGeneric(mask, types);

// after
boolean[] mask = {true, true, true};
Class<?>[] types = {Integer.class, String.class, Double.class};
format.setFieldsGeneric(mask, types);
Defensive patterns

Strategy: validation

Validate before calling

long selectedCount = Arrays.stream(includedMask).filter(b -> b).count();
if (selectedCount != fieldTypes.length) {
    throw new IllegalArgumentException(
        "included count (" + selectedCount + ") must equal fieldTypes.length (" + fieldTypes.length + ")");
}
format.setFieldsGeneric(includedMask, fieldTypes);

Type guard

static boolean maskAndTypesAligned(boolean[] mask, Class<?>[] types) {
    long trues = mask == null ? -1 : Arrays.stream(mask).filter(b -> b).count();
    return trues == (types == null ? -1 : types.length);
}

Prevention

When it happens

Trigger: includedMask has more true entries than fieldTypes.length; building the mask and types arrays from different sources that got out of sync; adding a column to the mask without adding its type.

Common situations: Schema evolution where a column was added to the selection but its type was forgotten; programmatic builders that construct mask and types separately; mismatched lengths after a refactor.

Related errors


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