apache/beam · error · IllegalArgumentException
Expected Map for type " + fieldType + ", but got: " +…
Error message
Expected Map for type " + fieldType + ", but got: " + value.getClass().getName()
What it means
MongoDbUtils.convertFromBsonValue is converting a BSON value into a Beam value for a schema field whose FieldType is MAP. It requires the raw Java value to already be a java.util.Map (e.g. a BSON Document), but the runtime value is some other class. This is a programming/configuration mismatch: the declared Beam schema does not match the shape of the data coming out of MongoDB.
Solutions
- Inspect the offending MongoDB document and correct the Beam schema FieldType (e.g. use a ROW or STRING type instead of MAP) to match the stored data.
- If the value is an array, change the field type to ARRAY<MAP<STRING,STRING>> so the iterable is unwrapped before the MAP case runs.
- Add a pre-conversion normalization step (custom DoFn) that converts non-Map BSON values (e.g. Document wrapped in other types) into java.util.Map before toRow.
- Pin/align the MongoDB Java driver version so decoded values are org.bson.Document (a Map) as expected.
Example fix
// before: schema field declared as MAP but data is scalar
fields.add(Field.of("attrs", FieldType.map(FieldType.STRING)));
// after: match the actual stored type (e.g. string JSON)
fields.add(Field.of("attrs", FieldType.STRING)); Defensive patterns
Strategy: validation
Validate before calling
if (!(bsonValue instanceof Map) && fieldType.getTypeName().equals(TypeName.MAP)) {
throw new IllegalStateException("Field expects a document but got: " + bsonValue.getClass());
} Type guard
static boolean isConvertibleMap(Object v) { return v instanceof java.util.Map; } Try / catch
try {
Row row = MongoDbUtils.toRow(doc, schema);
} catch (IllegalArgumentException e) {
LOG.error("BSON->Row conversion failed for schema {}: {}", schema, e.getMessage());
throw e;
} Prevention
- Derive the Beam schema from representative production documents, not a single sample.
- Log document class names for mismatched fields before conversion.
- Pin the MongoDB driver version in your build.
When it happens
Trigger: A field in the Beam schema is declared with FieldType MAP, but convertFromBsonValue receives a non-Map object for that field — e.g. the BSON value is a scalar, array, Document subclass variant, or a decoded type not implementing Map. Reached via toRow or recursively via convertFromBsonValue for nested collections.
Common situations: Schema auto-inference from a changed MongoDB document; storing a string or ObjectId where a map is expected; nested arrays of maps where the element type was inferred as MAP instead of ARRAY<MAP>; driver version changes altering decoded classes (Document vs RawBsonDocument).
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
- Cannot convert value of type " + (value != null ?…
- Collection element type cannot be null for type: " +…
- Expected Document but got " + (converted != null ?…
- Expected Iterable for type " + fieldType + ", but got: " +…
- Map value type cannot be null for type: " + fieldType
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9640a8b38761777e.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/mongodb/src/main/java/org/apache/beam/sdk/io/mongodb/MongoDbUtils.java:173
"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)) {
throw new IllegalArgumentException(
"Expected Map for type " + fieldType + ", but got: " + value.getClass().getName());
}
Map<?, ?> map = (Map<?, ?>) value;
Map<String, @Nullable Object> rowMap = new HashMap<>();
FieldType valueType = fieldType.getMapValueType();
if (valueType == null) {
throw new IllegalArgumentException(
"Map value type cannot be null for type: " + fieldType);
}
for (Map.Entry<?, ?> entry : map.entrySet()) {
rowMap.put(
String.valueOf(entry.getKey()), convertFromBsonValue(entry.getValue(), valueType));
}
return rowMap;
case ROW:
Schema rowSchema = fieldType.getRowSchema();
if (rowSchema == null) {
throw new IllegalArgumentException("Row schema cannot be null for type: " + fieldType);View on GitHub (pinned to 12126d8942)