prestodb/presto · error · IllegalArgumentException
Invalid map block:
Error message
Invalid map block:
What it means
ColumnarMap.toColumnarMap only understands map blocks that extend AbstractMapBlock (plus RunLengthEncodedBlock). When handed a Block of any other concrete type (e.g. a plain BlockBuilder output, IntArrayBlock, or a decoded/lazy block that was not yet compaction into a map representation), it throws IllegalArgumentException with the offending class name appended. This is a defensive type check because the method casts the block to AbstractMapBlock immediately afterwards.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/ColumnarMap.java:47
private final Block keysBlock;
private final Block valuesBlock;
private final int[] hashTables;
private final long retainedSizeInBytes;
private final long estimatedSerializedSizeInBytes;
public static ColumnarMap toColumnarMap(Block block)
{
requireNonNull(block, "block is null");
if (block instanceof DictionaryBlock) {
return toColumnarMap((DictionaryBlock) block);
}
if (block instanceof RunLengthEncodedBlock) {
return toColumnarMap((RunLengthEncodedBlock) block);
}
if (!(block instanceof AbstractMapBlock)) {
throw new IllegalArgumentException("Invalid map block: " + block.getClass().getName());
}
AbstractMapBlock mapBlock = (AbstractMapBlock) block;
int offsetBase = mapBlock.getOffsetBase();
int[] offsets = mapBlock.getOffsets();
// get the keys and values for visible region
int firstEntryPosition = mapBlock.getOffset(0);
int totalEntryCount = mapBlock.getOffset(block.getPositionCount()) - firstEntryPosition;
Block keysBlock = mapBlock.getRawKeyBlock().getRegion(firstEntryPosition, totalEntryCount);
Block valuesBlock = mapBlock.getRawValueBlock().getRegion(firstEntryPosition, totalEntryCount);
int[] hashTables = mapBlock.getHashTables().get();
return new ColumnarMap(
block,
offsetBase,
offsets,View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the Block being passed is actually a MAP-typed column (check the Type of the page column before converting)
- Call LazyBlock.unwrap() on the block (or Page.getBlock) before invoking toColumnarMap so lazy/dictionary-decorated blocks resolve to the real AbstractMapBlock
- Ensure custom Block implementations for maps extend AbstractMapBlock
- Check the exception message for the actual class name of the block and fix the upstream code producing that block
Example fix
// before Block block = page.getBlock(1); ColumnarMap map = ColumnarMap.toColumnarMap(block); // throws if lazy/unwrapped // after Block block = page.getBlock(1).getLoadedBlock(); checkArgument(block instanceof AbstractMapBlock || block instanceof RunLengthEncodedBlock, "Expected map block, got %s", block.getClass().getSimpleName()); ColumnarMap map = ColumnarMap.toColumnarMap(block);
Defensive patterns
Strategy: type-guard
Validate before calling
public static ColumnarMap safeToColumnarMap(Block block)
{
Block loaded = block.getLoadedBlock();
checkArgument(loaded instanceof AbstractMapBlock || loaded instanceof RunLengthEncodedBlock,
"Expected map block, got %s", loaded.getClass().getName());
return ColumnarMap.toColumnarMap(loaded);
} Type guard
static boolean isMapBlock(Block block) {
Block b = block.getLoadedBlock();
return b instanceof AbstractMapBlock || b instanceof RunLengthEncodedBlock;
} Try / catch
try {
ColumnarMap map = ColumnarMap.toColumnarMap(block);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Cannot convert column to map: " + e.getMessage(), e);
} Prevention
- Always check the column Type is MapType before calling toColumnarMap
- Unwrap LazyBlocks (getLoadedBlock) before block-type checks
- Keep custom map Block implementations extending AbstractMapBlock
- Log block.getClass().getName() in connector code to catch producer bugs early
When it happens
Trigger: Calling ColumnarMap.toColumnarMap(block) or ColumnarMap.columnarMap(block) with a Block that is neither a RunLengthEncodedBlock nor an AbstractMapBlock — e.g. passing the wrong-typed column of a page, a block produced by a non-map writer, or an unwrapped lazy block.
Common situations: Page/column type mismatches in custom connectors or readers (e.g. ORC/Parquet readers that decode a MAP column into the wrong block class); skipping the LazyBlock.unwrap call before extracting columns; version changes where a custom Block implementation no longer extends AbstractMapBlock.
Related errors
- Invalid row block:
- New column does not have same number of rows as old column
- Declared positions (%s) does not match block %s's number of
- Offset is not monotonically ascending. offsets[%s]=%s, offse
- A null map must have zero entries
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/86edda50909c53f3.
Report an issue: GitHub.