apache/flink · error · InvalidFieldReferenceException
Invalid tuple field reference "{}".
Error message
Invalid tuple field reference "{}". What it means
Thrown by RowTypeInfo.getFlatFields when the fieldExpression does not match Row's field regex (which accepts integer indices like '0', string names like 'f0'/'userName', dotted nested expressions, or '*'/'_' wildcards). Note the message says 'tuple' — this is a legacy wording in the RowTypeInfo code. This is an InvalidFieldReferenceException.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/RowTypeInfo.java:106
}
public RowTypeInfo(TypeInformation<?>[] types, String[] fieldNames) {
super(Row.class, types);
checkNotNull(fieldNames, "FieldNames should not be null.");
checkArgument(
types.length == fieldNames.length, "Number of field types and names is different.");
checkArgument(!hasDuplicateFieldNames(fieldNames), "Field names are not unique.");
this.fieldNames = Arrays.copyOf(fieldNames, fieldNames.length);
}
@Override
public void getFlatFields(
String fieldExpression, int offset, List<FlatFieldDescriptor> result) {
Matcher matcher = PATTERN_NESTED_FIELDS_WILDCARD.matcher(fieldExpression);
if (!matcher.matches()) {
throw new InvalidFieldReferenceException(
"Invalid tuple field reference \"" + fieldExpression + "\".");
}
String field = matcher.group(0);
if ((field.equals(ExpressionKeys.SELECT_ALL_CHAR))
|| (field.equals(ExpressionKeys.SELECT_ALL_CHAR_SCALA))) {
// handle select all
int keyPosition = 0;
for (TypeInformation<?> fType : types) {
if (fType instanceof CompositeType) {
CompositeType<?> cType = (CompositeType<?>) fType;
cType.getFlatFields(
ExpressionKeys.SELECT_ALL_CHAR, offset + keyPosition, result);
keyPosition += cType.getTotalFields() - 1;
} else {
result.add(new FlatFieldDescriptor(offset + keyPosition, fType));
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Use a valid Row field expression: integer index ('0'), default name ('f0'), custom name (valid identifier), or '*'.
- Ensure custom Row field names are valid identifiers matching [\p{L}_$][\p{L}\p{Digit}_$]*.
- For nested Row/POJO fields inside a Row, use dot-separated expressions.
Example fix
// before
rowType.getFlatFields("my-field");
// after
rowType.getFlatFields("myField"); Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern ROW_FIELD =
Pattern.compile("([0-9]+|[\\p{L}_$][\\p{L}\\p{Digit}_$]*)(\\\.(.+))?");
void validateRowFieldExpr(String expr) {
if (expr == null || !ROW_FIELD.matcher(expr).matches()) {
throw new IllegalArgumentException(
"Invalid Row field expression: " + expr);
}
} Prevention
- Use valid identifiers or integer indices for Row fields.
- Remember the error message says 'tuple' but applies to Row — check the type if confused.
When it happens
Trigger: Calling tableEnv or DataStream operations on a Row-typed stream with keyBy("field-name"), getFlatFields(""), or getFlatFields("a."). Row field names default to 'f0','f1',... unless a RowTypeInfo with custom names was constructed. Expressions with invalid characters like spaces or hyphens fail the pattern.
Common situations: Developer uses a hyphenated or space-containing field name, or passes an empty string. Also occurs when a Row has custom field names set via RowTypeInfo(types, names) but the key references a name that doesn't match the regex (e.g. a name with a dot). Confusingly the error message says 'tuple' not 'Row', which can mislead.
Related errors
- Invalid format of Row field expression "{}".
- Invalid POJO field reference "{}".
- Unable to find field "{}" in type {}.
- Invalid format of POJO field expression "{}".
- Nested field expression "{}" not possible on atomic type {}.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/fd849d913dccf62e.
Report an issue: GitHub.