apache/flink · error · IllegalArgumentException
A flattened field can not be a composite type
Error message
A flattened field can not be a composite type
What it means
Thrown by the FlatFieldDescriptor constructor when the supplied TypeInformation is itself a CompositeType (i.e. Tuple, POJO, Row). A FlatFieldDescriptor represents a fully flattened leaf field, which by definition must be an atomic (non-composite) type. Constructing one with a composite type signals a bug in field-expression resolution.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/typeutils/CompositeType.java:208
// --------------------------------------------------------------------------------------------
@PublicEvolving
protected interface TypeComparatorBuilder<T> {
void initializeTypeComparatorBuilder(int size);
void addComparatorField(int fieldId, TypeComparator<?> comparator);
TypeComparator<T> createTypeComparator(ExecutionConfig config);
}
@PublicEvolving
public static class FlatFieldDescriptor {
private int keyPosition;
private TypeInformation<?> type;
public FlatFieldDescriptor(int keyPosition, TypeInformation<?> type) {
if (type instanceof CompositeType) {
throw new IllegalArgumentException("A flattened field can not be a composite type");
}
this.keyPosition = keyPosition;
this.type = type;
}
public int getPosition() {
return keyPosition;
}
public TypeInformation<?> getType() {
return type;
}
@Override
public String toString() {
return "FlatFieldDescriptor [position=" + keyPosition + " typeInfo=" + type + "]";
}
}View on GitHub (pinned to 2f3c205e92)
Solutions
- If implementing a custom CompositeType, ensure getFlatFields recurses into nested composite types until only atomic FlatFieldDescriptors remain.
- If you are a user hitting this via keyBy or field selectors, check that your field expression targets a leaf field, not a nested composite object.
- Avoid selecting a whole nested object as a key; instead select a specific field within it (e.g. 'nested.id' not 'nested').
Example fix
// before — selecting a nested composite object as a flat key
// class Outer { Nested nested; } class Nested { int id; }
ds.keyBy("nested") // resolves to composite Nested -> FlatFieldDescriptor rejects
// after — select the leaf atomic field
ds.keyBy("nested.id") // ok Defensive patterns
Strategy: validation
Validate before calling
// If building FlatFieldDescriptor manually, guard against composite types
TypeInformation<?> fieldType = compositeType.getTypeAt(pos);
if (fieldType instanceof CompositeType) {
throw new IllegalStateException(
"Field at " + pos + " is composite; drill into a leaf field instead.");
}
FlatFieldDescriptor desc = new FlatFieldDescriptor(pos, fieldType); Prevention
- When selecting keys via field expressions, always target leaf atomic fields, not whole nested objects.
- If implementing a custom CompositeType, ensure getFlatFields recurses to atomic leaves only.
When it happens
Trigger: Internal code or a custom CompositeType subclass calling new FlatFieldDescriptor(pos, compositeTypeInfo). Also triggered when a field expression with a trailing dot or wildcard resolves to a composite type instead of drilling down to an atomic field. This is primarily an internal invariant, not a user-facing API in most cases.
Common situations: Implementing a custom CompositeType with a buggy getFlatFields override that stops at a composite field. A field expression like "nested." (trailing dot) or an empty selector on a nested tuple that does not recurse. Flink version mismatch where a custom type's field resolution logic changed.
Related errors
- Could not add a comparator for the logicalkey field index {}
- The elements in the collection are not all subclasses of {vi
- The elements in the collection are not all subclasses of {vi
- The type '{}' is not supported for the CSV input format.
- No parser available for type '{}'.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/5018eafa8e500ec2.
Report an issue: GitHub.