apache/beam · error · IllegalArgumentException

Unsupported field type: {fieldType}

Error message

Unsupported field type: {fieldType}

What it means

javaToValue switches over the FieldType's TypeName; any type not explicitly handled (the default branch) is unsupported for Firestore serialization and triggers IllegalArgumentException('Unsupported field type: ...'). This acts as the exhaustive-check for the converter's supported type set.

Source

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

        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) {
      return null;
    }
    switch (fieldType.getTypeName()) {
      case BYTE:
        return ((Number) value).byteValue();
      case INT16:
        return ((Number) value).shortValue();
      case INT32:
        return ((Number) value).intValue();
      case INT64:
        return ((Number) value).longValue();
      case FLOAT:
        return ((Number) value).floatValue();

View on GitHub (pinned to 12126d8942)

Solutions

  1. Check the FieldType before writing and convert unsupported fields to supported ones (string, numeric, boolean, bytes, array, map, row, timestamp)
  2. Use FieldType.withLogicalType only if the underlying storage type is supported
  3. Drop or project out unsupported columns upstream with a Select/Map transform
  4. Upgrade the Beam connector, which may cover more types

Example fix

// before
Schema schema = Schema.builder().addField("custom", FieldType.logicalType(myLogic)).build(); // unsupported
// after
Schema schema = Schema.builder().addStringField("custom").build(); // serialize to string first
Defensive patterns

Strategy: validation

Validate before calling

for (Field f : schema.getFields()) {
  switch (f.getType().getTypeName()) {
    case STRING: case INT64: case DOUBLE: case BOOLEAN: case BYTES:
    case ARRAY: case ITERABLE: case MAP: case ROW: case DATETIME: break;
    default: throw new IllegalStateException("Unsupported for Firestore: " + f.getType());
  }
}

Prevention

When it happens

Trigger: Writing a Row containing a field whose type has no Firestore mapping — e.g. BYTES variants not handled, DATETIME/logical types, or exotic custom logical types — through Firestore IO writes via rowToDocument.

Common situations: Schemas auto-generated from sources with types Firestore can't represent (e.g. Kafka Connect complex types); Beam logical-type fields; upgrading schemas to include new Beam TypeName values on an older connector.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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