apache/beam · error · IllegalArgumentException
Expected Row for nested field.
Error message
Expected Row for nested field.
What it means
When javaToValue converts a ROW-typed field, the actual Java value must be an instance of Beam's Row class so its fields can be read and serialized to a Firestore MapValue. If the value is any other object (or null handled elsewhere), the type contract is broken and it throws IllegalArgumentException('Expected Row for nested field.').
Solutions
- Wrap nested data in a Row created with the same nested schema before writing
- Convert Maps/POJOs to Row via Row.withSchema(nestedSchema).attachValues(...) or rowFromMap-style helpers
- Align the field's FieldType.row(schema) with the actual value type produced upstream
Example fix
// before
Row row = Row.withSchema(schema).addValues(new HashMap<>(nestedMap)).build(); // Map in ROW slot
// after
Row nested = Row.withSchema(nestedSchema).attachValues("a", 1);
Row row = Row.withSchema(schema).addValues(nested).build(); Defensive patterns
Strategy: type-guard
Validate before calling
Object v = row.getValue("nestedField");
if (v != null && !(v instanceof Row)) {
throw new IllegalStateException("nestedField must be a Row, got " + v.getClass());
} Type guard
static boolean isNestedRow(Object v) { return v instanceof Row; } Try / catch
try {
Document doc = FirestoreUtils.rowToDocument(row, projectId, databaseId, collectionId, idField);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Expected Row for nested field")) {
log.error("Nested field is not a Row in: {}", row);
}
throw e;
} Prevention
- Convert Maps/POJOs to Row before inserting into parent Rows
- Keep nested value construction and schema definition adjacent in code
- Add a unit test writing a fully populated nested Row
When it happens
Trigger: Supplying a Map, POJO, or JSON object for a field declared ROW in the schema when writing Rows to Firestore; schema and data built by different code paths that disagree on representation.
Common situations: Passing HashMap instead of Row for a nested record; a transform upstream that decoded JSON into a Map and inserted it into the Row; using generic row getValue with the wrong field index.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Expected Iterable for array field.
- Can't cast non-numeric types: +input
- Can't cast numbers to non-numeric type: +output
- Cannot convert BigQuery type '' to '' because the BigQuery…
- Cannot convert value to Row.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/db0dfc32d01566a6.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/firestore/FirestoreUtils.java:214
}
for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
Object mapValue = entry.getValue();
mapBuilder.putFields(
String.valueOf(entry.getKey()),
mapValue == null
? Value.newBuilder()
.setNullValue(com.google.protobuf.NullValue.NULL_VALUE)
.build()
: javaToValue(mapValue, valueType));
}
return Value.newBuilder().setMapValue(mapBuilder.build()).build();
case ROW:
Schema rowSchema = fieldType.getRowSchema();
if (rowSchema == null) {
throw new IllegalArgumentException("Row schema cannot be null.");
}
if (!(value instanceof Row)) {
throw new IllegalArgumentException("Expected Row for nested field.");
}
MapValue.Builder nestedMapBuilder = MapValue.newBuilder();
Row nestedRow = (Row) value;
for (Field nestedField : rowSchema.getFields()) {
Object nestedValue = nestedRow.getValue(nestedField.getName());
if (nestedValue != null) {
nestedMapBuilder.putFields(
nestedField.getName(), javaToValue(nestedValue, nestedField.getType()));
}
}
return Value.newBuilder().setMapValue(nestedMapBuilder.build()).build();
default:
throw new IllegalArgumentException("Unsupported field type: " + fieldType);
}
}
private static @Nullable Object convertFromJava(@Nullable Object value, FieldType fieldType) {
if (value == null) {View on GitHub (pinned to 12126d8942)