{"record":{"id":"db0dfc32d01566a6","repo":"apache/beam","slug":"expected-row-for-nested-field","errorCode":null,"errorMessage":"Expected Row for nested field.","messagePattern":"Expected Row for nested field\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/firestore/FirestoreUtils.java","lineNumber":214,"sourceCode":"        }\n        for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {\n          Object mapValue = entry.getValue();\n          mapBuilder.putFields(\n              String.valueOf(entry.getKey()),\n              mapValue == null\n                  ? Value.newBuilder()\n                      .setNullValue(com.google.protobuf.NullValue.NULL_VALUE)\n                      .build()\n                  : javaToValue(mapValue, valueType));\n        }\n        return Value.newBuilder().setMapValue(mapBuilder.build()).build();\n      case ROW:\n        Schema rowSchema = fieldType.getRowSchema();\n        if (rowSchema == null) {\n          throw new IllegalArgumentException(\"Row schema cannot be null.\");\n        }\n        if (!(value instanceof Row)) {\n          throw new IllegalArgumentException(\"Expected Row for nested field.\");\n        }\n        MapValue.Builder nestedMapBuilder = MapValue.newBuilder();\n        Row nestedRow = (Row) value;\n        for (Field nestedField : rowSchema.getFields()) {\n          Object nestedValue = nestedRow.getValue(nestedField.getName());\n          if (nestedValue != null) {\n            nestedMapBuilder.putFields(\n                nestedField.getName(), javaToValue(nestedValue, nestedField.getType()));\n          }\n        }\n        return Value.newBuilder().setMapValue(nestedMapBuilder.build()).build();\n      default:\n        throw new IllegalArgumentException(\"Unsupported field type: \" + fieldType);\n    }\n  }\n\n  private static @Nullable Object convertFromJava(@Nullable Object value, FieldType fieldType) {\n    if (value == null) {","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/firestore/FirestoreUtils.java#L196-L232","documentation":"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.').","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nRow row = Row.withSchema(schema).addValues(new HashMap<>(nestedMap)).build(); // Map in ROW slot\n// after\nRow nested = Row.withSchema(nestedSchema).attachValues(\"a\", 1);\nRow row = Row.withSchema(schema).addValues(nested).build();","handlingStrategy":"type-guard","validationCode":"Object v = row.getValue(\"nestedField\");\nif (v != null && !(v instanceof Row)) {\n  throw new IllegalStateException(\"nestedField must be a Row, got \" + v.getClass());\n}","typeGuard":"static boolean isNestedRow(Object v) { return v instanceof Row; }","tryCatchPattern":"try {\n  Document doc = FirestoreUtils.rowToDocument(row, projectId, databaseId, collectionId, idField);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Expected Row for nested field\")) {\n    log.error(\"Nested field is not a Row in: {}\", row); \n  }\n  throw e;\n}","preventionTips":["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"],"tags":["java","apache-beam","firestore","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}