apache/flink · error · IllegalArgumentException
Accessing a field by position is not supported in name-based
Error message
Accessing a field by position is not supported in name-based field mode.
What it means
Row supports two access modes: position-based (fields stored in an array, fieldByPosition != null) and name-based (fields in a map). getField(int pos) only works in position-based mode; if the row was created with Row.withNames() / Row.ofKind-with-names (so only fieldByName/positionByName exist and fieldByPosition is null), positional access is rejected with this IllegalArgumentException.
Source
Thrown at flink-core/src/main/java/org/apache/flink/types/Row.java:257
} else {
assert fieldByName != null;
return fieldByName.size();
}
}
/**
* Returns the field's content at the specified field position.
*
* <p>Note: The row must operate in position-based field mode.
*
* @param pos the position of the field, 0-based
* @return the field's content at the specified position
*/
public @Nullable Object getField(int pos) {
if (fieldByPosition != null) {
return fieldByPosition[pos];
} else {
throw new IllegalArgumentException(
"Accessing a field by position is not supported in name-based field mode.");
}
}
/**
* Returns the field's content at the specified field position.
*
* <p>Note: The row must operate in position-based field mode.
*
* <p>This method avoids a lot of manual casting in the user implementation.
*
* @param pos the position of the field, 0-based
* @return the field's content at the specified position
*/
@SuppressWarnings("unchecked")
public <T> T getFieldAs(int pos) {
return (T) getField(pos);
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Use getField(String name) / getFieldAs(name, type) on name-based rows
- Create the row position-based with Row.of(...) / Row.ofKind(...) if positional access is required
- Branch on the mode with row.getFieldNames(true) != null before access, or normalize rows to one mode at the boundary
Example fix
// before
Row row = Row.withNames();
row.setField("id", 42);
Object v = row.getField(0); // throws
// after
Object v = row.getField("id"); Defensive patterns
Strategy: type-guard
Validate before calling
boolean positionBased = row.getFieldNames(true) == null || /* hybrid rows also have fieldByPosition */ row.getField(0) != null;
Type guard
static boolean isPositionBased(Row row) {
return row.getFieldNames(true) == null;
}
// usage: if (isPositionBased(row)) v = row.getField(pos); else v = row.getField(name); Try / catch
catch (IllegalArgumentException e) { throw new IllegalStateException("Row mode mismatch; expected position-based", e); } Prevention
- Standardize one Row mode per pipeline
- Create rows with Row.of(...) when positional access is needed
- Convert modes at system boundaries
When it happens
Trigger: Calling row.getField(pos) on a Row created via Row.withNames(), Row.withNames(RowKind, ...), or one whose fields were set via setField(String, Object); also hybrid rows where only names were provided.
Common situations: Connector or function code written for position-based rows receiving name-based rows produced by the Table/SQL layer or a source that sets field names; mixing Row.of(...) and Row.withNames() creation paths in one pipeline.
Related errors
- Accessing a field by name is not supported in position-based
- Unknown field name '%s' for mapping to a position.
- Unknown field name '%s' for mapping to a row position. Avail
- Length must be between 0 and the current length.
- Cannot find empty string.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/01b2a34d6d7a934e.
Report an issue: GitHub.