apache/flink · error · InvalidFieldReferenceException
Nested field expression "{}" not possible on atomic type {}.
Error message
Nested field expression "{}" not possible on atomic type {}. What it means
Thrown by PojoTypeInfo.getFlatFields when a nested field expression (e.g. "myField.subField") references a field whose TypeInformation is atomic (not a CompositeType). You cannot drill into a scalar/basic type with a dot-separated tail. This is an InvalidFieldReferenceException.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/PojoTypeInfo.java:229
((CompositeType<?>) fieldType).getFlatFields("*", offset, result);
} else {
// we found the field to add
// compute flat field position by adding skipped fields
int flatFieldPos = offset;
for (int i = 0; i < fieldPos; i++) {
flatFieldPos += this.getTypeAt(i).getTotalFields();
}
result.add(new FlatFieldDescriptor(flatFieldPos, fieldType));
}
} else {
if (fieldType instanceof CompositeType<?>) {
// forward offset
for (int i = 0; i < fieldPos; i++) {
offset += this.getTypeAt(i).getTotalFields();
}
((CompositeType<?>) fieldType).getFlatFields(tail, offset, result);
} else {
throw new InvalidFieldReferenceException(
"Nested field expression \""
+ tail
+ "\" not possible on atomic type "
+ fieldType
+ ".");
}
}
}
@SuppressWarnings("unchecked")
@Override
@PublicEvolving
public <X> TypeInformation<X> getTypeAt(String fieldExpression) {
Matcher matcher = PATTERN_NESTED_FIELDS.matcher(fieldExpression);
if (!matcher.matches()) {
if (fieldExpression.startsWith(ExpressionKeys.SELECT_ALL_CHAR)
|| fieldExpression.startsWith(ExpressionKeys.SELECT_ALL_CHAR_SCALA)) {View on GitHub (pinned to 2f3c205e92)
Solutions
- Remove the nested '.tail' from the key expression — reference the field directly.
- If nesting is intended, verify the field's type is actually a CompositeType (POJO, Tuple, or Row) by printing its TypeInformation.
- If the nested type was misclassified as generic/atomic, add proper POJO annotations or a public constructor/getter/setter to make it a recognized composite.
Example fix
// before
stream.keyBy("timestamp.millis"); // timestamp is a long (atomic)
// after
stream.keyBy("timestamp"); Defensive patterns
Strategy: validation
Validate before calling
TypeInformation<?> fieldType =
((CompositeType<?>) TypeInformation.of(MyPojo.class)).getTypeAt(fieldName);
if (!(fieldType instanceof CompositeType)) {
throw new IllegalArgumentException(
"Cannot nest into atomic field '" + fieldName
+ "' of type " + fieldType);
} Type guard
boolean isCompositeField(CompositeType<?> type, String field) {
return type.getTypeAt(field) instanceof CompositeType;
} Prevention
- Before using dotted field expressions, verify the intermediate field is a CompositeType.
- Inspect nested field types during development via TypeInformation.
When it happens
Trigger: Calling keyBy("myString.length") where myString is a String field (atomic), or keyBy("count.value") where count is a primitive int/Integer. The matcher.group(3) returns a non-null tail but fieldType is not instanceof CompositeType.
Common situations: Developer assumes a field is a nested POJO or Tuple but the type extractor resolved it to a basic/atomic type. Common with boxed primitives, String fields, or when a nested class was not recognized as a POJO and fell back to a generic/atomic type.
Related errors
- Nested field expression "{}" not possible on atomic type {}.
- Nested field expression "{}" not possible on atomic type {}.
- Invalid POJO field reference "{}".
- Unable to find field "{}" in type {}.
- Wildcard expressions are not allowed here.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/ba0244d3c129122e.
Report an issue: GitHub.