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

  1. Remove the nested '.tail' from the key expression — reference the field directly.
  2. If nesting is intended, verify the field's type is actually a CompositeType (POJO, Tuple, or Row) by printing its TypeInformation.
  3. 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

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


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