apache/flink · error · IllegalArgumentException
Accessing a field by name is not supported in position-based
Error message
Accessing a field by name is not supported in position-based field mode.
What it means
Mirror of the positional case: getField(String name) requires name-based mode. If the row was created position-based (Row.of(...), Row.ofKind(...)) then fieldByName and positionByName are both null, and any by-name access is rejected with this IllegalArgumentException because no name information exists.
Source
Thrown at flink-core/src/main/java/org/apache/flink/types/Row.java:297
*
* <p>Note: The row must operate in name-based field mode.
*
* @param name the name of the field or null if not set previously
* @return the field's content
*/
public @Nullable Object getField(String name) {
if (fieldByName != null) {
return fieldByName.get(name);
} else if (positionByName != null) {
final Integer pos = positionByName.get(name);
if (pos == null) {
throw new IllegalArgumentException(
String.format("Unknown field name '%s' for mapping to a position.", name));
}
assert fieldByPosition != null;
return fieldByPosition[pos];
} else {
throw new IllegalArgumentException(
"Accessing a field by name is not supported in position-based field mode.");
}
}
/**
* Returns the field's content using the specified field name.
*
* <p>Note: The row must operate in name-based field mode.
*
* <p>This method avoids a lot of manual casting in the user implementation.
*
* @param name the name of the field, set previously
* @return the field's content
*/
@SuppressWarnings("unchecked")
public <T> T getFieldAs(String name) {
return (T) getField(name);
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Use getField(int pos) on position-based rows
- Create the row with Row.withNames() if named access is required
- Convert at the boundary: build a hybrid row by attaching names (Row.withPositions + setField names) before handing it to name-based consumers
Example fix
// before
Row row = Row.of(42, "alice");
Object v = row.getField("id"); // throws
// after
Object v = row.getField(0); Defensive patterns
Strategy: type-guard
Validate before calling
if (row.getFieldNames(true) == null) {
throw new IllegalArgumentException("Row has no field names; use positional access");
} Type guard
static boolean isNameBased(Row row) {
return row.getFieldNames(true) != null;
} Try / catch
catch (IllegalArgumentException e) { throw new IllegalStateException("Row mode mismatch; expected name-based", e); } Prevention
- Use Row.withNames() when named access is required
- Keep accessor style consistent with creation style
- Normalize at boundaries
When it happens
Trigger: Calling getField(String) / getFieldAs(String, Class) on a Row created with Row.of(...) or Row.ofKind(...) where no field names were ever attached.
Common situations: Table/SQL-derived code assuming named access receiving raw position-based rows from DataStream sources or UDF output; refactoring a row creation site from withNames() to of() without updating readers.
Related errors
- Accessing a field by position is not supported in name-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/a11a565d32142fd9.
Report an issue: GitHub.