apache/beam · error · IllegalArgumentException

Expected Iterable for type " + fieldType + ", but got: " +…

Error message

Expected Iterable for type " + fieldType + ", but got: " + value.getClass().getName()

What it means

In MongoDbUtils.convertFromBsonValue, when the Beam schema field type is ARRAY or ITERABLE, the BSON value must itself be an Iterable. If a scalar (or non-iterable value) appears where an array was declared, this IllegalArgumentException is thrown naming the field type and actual value class.

Solutions

  1. Align the Row schema field type with the actual BSON type (declare it scalar if the data is scalar)
  2. Cleanse/migrate MongoDB data so the field is consistently an array
  3. Pre-filter or normalize documents (e.g., wrap scalars in a single-element list) before conversion

Example fix

// before
// schema: "tags" ARRAY<STRING>, document: { "tags": "one-tag" }
// after
// normalize document before reading:
doc.put("tags", doc.get("tags") instanceof List ? doc.get("tags") : List.of((String) doc.get("tags")));
Defensive patterns

Strategy: validation

Validate before calling

Object tags = doc.get("tags");
if (!(tags instanceof Iterable)) {
  throw new IllegalArgumentException("Field 'tags' declared ARRAY but value is " + (tags == null ? "null" : tags.getClass()));
}

Type guard

static boolean isIterableValue(Object value) {
  return value instanceof Iterable;
}

Try / catch

try {
  Row row = MongoDbUtils.toRow(doc, schema);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Expected Iterable for type")) {
    // coerce scalar to single-element list or fix schema type
  }
}

Prevention

When it happens

Trigger: Reading MongoDB documents where a field declared as ARRAY/ITERABLE in the Row schema holds a non-array BSON value (string, int, object) — e.g., schema says array but some documents store a scalar.

Common situations: Heterogeneous MongoDB collections where a field evolved from scalar to array (or vice versa); schema defined from a sample document that doesn't match all documents.

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


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

Appendix: source

Thrown at sdks/java/io/mongodb/src/main/java/org/apache/beam/sdk/io/mongodb/MongoDbUtils.java:154

        if (value instanceof java.util.Date) {
          return new Instant(((java.util.Date) value).getTime());
        } else if (value instanceof Number) {
          return new Instant(((Number) value).longValue());
        } else {
          return Instant.parse(value.toString());
        }
      case BYTES:
        if (value instanceof Binary) {
          return ((Binary) value).getData();
        } else if (value instanceof byte[]) {
          return (byte[]) value;
        } else {
          return value.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
        }
      case ARRAY:
      case ITERABLE:
        if (!(value instanceof Iterable)) {
          throw new IllegalArgumentException(
              "Expected Iterable for type "
                  + fieldType
                  + ", but got: "
                  + value.getClass().getName());
        }
        Iterable<?> iterable = (Iterable<?>) value;
        List<@Nullable Object> rowList = new ArrayList<>();
        FieldType elementType = fieldType.getCollectionElementType();
        if (elementType == null) {
          throw new IllegalArgumentException(
              "Collection element type cannot be null for type: " + fieldType);
        }
        for (Object item : iterable) {
          rowList.add(convertFromBsonValue(item, elementType));
        }
        return rowList;
      case MAP:
        if (!(value instanceof Map)) {

View on GitHub (pinned to 12126d8942)