apache/seatunnel · error · java.lang.IllegalArgumentException
Map type requires Map value, got: ${value.getClass()}
Error message
Map type requires Map value, got: ${value.getClass()} What it means
FragmentConverter.writeMapToVector throws this IllegalArgumentException when writing a SeaTunnel MAP column into an Arrow MapVector but the runtime value is not a java.util.Map. The converter requires an exact Map instance to iterate key/value pairs; anything else (String, List, POJO) cannot be written as map entries. It is a data/type contract violation between the SeaTunnel row and the Lance/Arrow schema.
Source
Thrown at seatunnel-connectors-v2/connector-lance/src/main/java/org/apache/seatunnel/connectors/seatunnel/lance/utils/FragmentConverter.java:139
Field elementField = children.get(0);
ArrowType elementType = elementField.getType();
for (Object element : listValue) {
writeListElement(writer, elementType, element, allocator);
}
writer.setValueCount(listValue.size());
writer.endList();
}
private static void writeMapToVector(
MapVector mapVector,
Field field,
Object value,
int rowIndex,
BufferAllocator allocator) {
if (!(value instanceof java.util.Map)) {
throw new IllegalArgumentException(
"Map type requires Map value, got: " + value.getClass());
}
UnionMapWriter writer = mapVector.getWriter();
writer.setPosition(rowIndex);
writer.startMap();
java.util.Map<?, ?> mapValue = (java.util.Map<?, ?>) value;
List<Field> children = field.getChildren();
if (children.size() < 2) {
throw new IllegalArgumentException("Map field must have key and value child fields");
}
Field keyField = children.get(0);
Field valueField = children.get(1);
ArrowType keyType = keyField.getType();
ArrowType valueType = valueField.getType();
for (java.util.Map.Entry<?, ?> entry : mapValue.entrySet()) {View on GitHub (pinned to cf67b549a7)
Solutions
- Fix the upstream source/transform so the MAP column carries an actual java.util.Map value
- Cast or convert the value (e.g. parse JSON string to Map) before writing
- Verify the SeaTunnel catalog schema declares the column as MAP and matches the data
- Add a pre-write type check/logging to identify which column and row carries the bad value
Example fix
// before
Object value = row.getField(mapColIndex); // value is a JSON string
converter.setVectorValue(mapVector, field, value, i, allocator); // throws
// after
Object value = row.getField(mapColIndex);
if (!(value instanceof java.util.Map) && value instanceof String) {
value = new com.fasterxml.jackson.databind.ObjectMapper()
.readValue((String) value, java.util.Map.class);
}
converter.setVectorValue(mapVector, field, value, i, allocator); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(value instanceof java.util.Map)) {
throw new IllegalArgumentException("Column '" + field.getName() + "' expects a java.util.Map, got: "
+ (value == null ? "null" : value.getClass().getName()));
} Type guard
boolean isWritableMap(Object v) {
return v instanceof java.util.Map;
} Try / catch
try {
converter.setVectorValue(mapVector, field, value, rowIndex, allocator);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Map type requires Map value")) {
LOG.warn("Skipping non-map value {} at row {} column {}", value, rowIndex, field.getName());
} else {
throw e;
}
} Prevention
- Enforce SeaTunnel MAP column types in the source so values are materialized as java.util.Map
- Add row-level schema validation before writing to Arrow vectors
- Log value classes of MAP columns during connector development
- Convert JSON-string map columns to Map in an upstream transform
When it happens
Trigger: setVectorValue dispatches a row field whose SeaTunnel type is MAP_ARRAY/MAP to writeMapToVector, but the Object value at rowIndex is not a java.util.Map (e.g. it is a String, List, or null-wrapped wrapper).
Common situations: Custom source connectors emitting raw JSON strings for map columns; data read from formats that deserialize maps into LinkedHashMap alternatives or Lists of pairs; upstream transforms producing wrong column types; schema mismatch after table definition changes.
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
- Unsupported timestamp value type:
- Unsupported date value type:
- Map type should be handled via FragmentConverter.writeMapToV
- List type requires List value, got: ${value.getClass()}
- TABLE_DATASET_WRITE_ST_ROW_EXCEPTION
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/2a794e6881b3fc98.
Report an issue: GitHub.