prestodb/presto · error · IllegalArgumentException
Type must be a MapType for MapVector
Error message
Type must be a MapType for MapVector
What it means
assignBlockFromMapVector converts an Arrow MapVector into a Presto map block. It requires the Presto Type to be MapType because it needs the map's key/value types to build BlockMapGetter-style accessors and recursively convert entries. A non-MapType makes this impossible, so it throws this IllegalArgumentException.
Source
Thrown at presto-common-arrow/src/main/java/com/facebook/plugin/arrow/ArrowBlockBuilder.java:724
throw new IllegalArgumentException("Expected TimestampType but got " + type.getClass().getName());
}
for (int i = startIndex; i < endIndex; i++) {
if (vector.isNull(i)) {
builder.appendNull();
}
else {
long micros = vector.get(i);
long millis = TimeUnit.MICROSECONDS.toMillis(micros);
type.writeLong(builder, millis);
}
}
}
public void assignBlockFromMapVector(MapVector vector, Type type, BlockBuilder builder, int startIndex, int endIndex)
{
if (!(type instanceof MapType)) {
throw new IllegalArgumentException("Type must be a MapType for MapVector");
}
MapType mapType = (MapType) type;
StructVector entryVector = (StructVector) vector.getDataVector();
ValueVector keyVector = entryVector.getChildByOrdinal(0);
ValueVector valueVector = entryVector.getChildByOrdinal(1);
for (int i = startIndex; i < endIndex; i++) {
if (vector.isNull(i)) {
builder.appendNull();
}
else {
BlockBuilder entryBuilder = builder.beginBlockEntry();
int entryStart = vector.getElementStartIndex(i);
int entryEnd = vector.getElementEndIndex(i);
for (int entryIndex = entryStart; entryIndex < entryEnd; entryIndex++) {
assignBlockFromValueVector(keyVector, mapType.getKeyType(), entryBuilder, entryIndex, entryIndex + 1);
assignBlockFromValueVector(valueVector, mapType.getValueType(), entryBuilder, entryIndex, entryIndex + 1);View on GitHub (pinned to 55bb57d202)
Solutions
- Declare the Presto column as a map of matching key/value types (MapType)
- Fix the Type supplied in the assignBlockFromValueVector dispatch so the MapVector gets its own MapType
- Verify the Arrow child field (keys/values) types match the Presto map's key/value types
Example fix
// before assignBlockFromMapVector(mapVector, ArrayType.from(rowType), builder, start, end); // after assignBlockFromMapVector(mapVector, MapType.from(keyType, valueType), builder, start, end);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(columnType instanceof MapType)) {
throw new IllegalStateException("Column '" + name + "' must be MapType to receive MapVector, got " + columnType);
} Type guard
boolean isMapColumn(Type type) {
return type instanceof MapType;
} Try / catch
try {
builder.assignBlockFromMapVector(vector, type, blockBuilder, start, end);
} catch (IllegalArgumentException e) {
if (!e.getMessage().contains("MapType for MapVector")) throw e;
// coerce (e.g. array(row) -> map) or fail with context
} Prevention
- Map Arrow MAP fields to map(k,v) Presto types, not array(row)
- Verify MapVector child (key/value) types match the declared MapType
- Keep Arrow-schema-derived metadata as the single source of truth
When it happens
Trigger: Calling assignBlockFromMapVector (directly or via assignBlockFromValueVector) with a non-MapType, e.g. an ARRAY or ROW column type paired with a MapVector, or a scalar type.
Common situations: Arrow producer encodes a column as MAP while the Presto table declares it as array(row) or json; schema mismatch after producer-side type change; column-index misalignment in the dispatch switch.
Related errors
- Invalid map block:
- Type must be a DecimalType for DecimalVector
- Expected TimestampType but got {type.getClass().getName()}
- Expected VarcharType but got {type.getClass().getName()}
- Expected DateType but got {type.getClass().getName()}
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1b7422c6934fa687.
Report an issue: GitHub.