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 TupleTypeInfoBase.getFlatFields when a nested expression (e.g. "f0.sub") references a tuple field whose TypeInformation is atomic (not a CompositeType). You cannot drill into a scalar with a dot-separated tail. This is an InvalidFieldReferenceException.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TupleTypeInfoBase.java:173

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

    @Override
    public <X> TypeInformation<X> getTypeAt(String fieldExpression) {

        Matcher matcher = PATTERN_NESTED_FIELDS.matcher(fieldExpression);
        if (!matcher.matches()) {
            if (fieldExpression.equals(ExpressionKeys.SELECT_ALL_CHAR)
                    || fieldExpression.equals(ExpressionKeys.SELECT_ALL_CHAR_SCALA)) {
                throw new InvalidFieldReferenceException(

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Remove the '.tail' — reference the atomic field directly (e.g. 'f0').
  2. If nesting is required, confirm the field's type is a CompositeType via tupleType.getTypeAt(pos).

Example fix

// before
tupleType.getFlatFields("f0.inner"); // f0 is String
// after
tupleType.getFlatFields("f0");
Defensive patterns

Strategy: type-guard

Validate before calling

TypeInformation<?> ft = tupleType.getTypeAt(fieldPos);
if (tail != null && !(ft instanceof CompositeType)) {
    throw new IllegalArgumentException(
        "Cannot nest into atomic " + ft);
}

Type guard

boolean canNestInto(TupleTypeInfoBase<?> type, int pos) {
    return type.getTypeAt(pos) instanceof CompositeType;
}

Prevention

When it happens

Trigger: Calling tupleType.getFlatFields("f0.length") where f0 is a String (atomic), or keyBy("f1.value") where f1 is an Integer. The tail (matcher.group(5)) is non-null but fieldType is not a CompositeType.

Common situations: Developer assumes a tuple field holds a nested Tuple/POJO but it is a basic type. Common when working with mixed tuples where only some fields are composite.

Related errors


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