apache/beam · error · IllegalArgumentException

Row schema cannot be null.

Error message

Row schema cannot be null.

What it means

javaToValue handles ROW-typed fields by serializing a nested Beam Row into a Firestore MapValue. It requires fieldType.getRowSchema() to be non-null; a ROW FieldType without an embedded Schema carries no information about the nested fields, so the converter throws IllegalArgumentException.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/firestore/FirestoreUtils.java:211

        FieldType valueType = fieldType.getMapValueType();
        if (valueType == null) {
          throw new IllegalArgumentException("Map value type cannot be null.");
        }
        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);
    }
  }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Create nested fields with FieldType.row(Schema) providing the nested schema
  2. Use Schema.builder().addRowField(name, nestedSchema) instead of raw TypeName construction
  3. Check field.getType().getRowSchema() for every nested field before writing

Example fix

// before
FieldType bad = FieldType.of(TypeName.ROW); // no nested schema
// after
FieldType good = FieldType.row(nestedSchema);
Defensive patterns

Strategy: validation

Validate before calling

FieldType ft = schema.getField(name).getType();
if (ft.getTypeName() == TypeName.ROW && ft.getRowSchema() == null) {
  throw new IllegalStateException("ROW field '" + name + "' lacks nested schema");
}

Prevention

When it happens

Trigger: Writing Rows containing nested Row fields where the FieldType was built as FieldType.of(TypeName.ROW) without passing the nested Schema.

Common situations: Manually composing FieldTypes for nested records and forgetting FieldType.row(schema); schemas built via reflection where nested row schemas weren't attached; deserialized schemas missing nested metadata.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/562b4e28a7afea52. Report an issue: GitHub.