prestodb/presto · error · IllegalArgumentException

Map keys must not be null

Error message

Map keys must not be null

What it means

appendStructure copies an existing map block into this MapBlockBuilder key-by-key. Presto maps forbid null keys, so when a key position in the source block is null the builder throws IllegalArgumentException rather than producing a corrupt map. Keys may be null only in unchecked SQL modes at the source, but internally the invariant must hold.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/MapBlockBuilder.java:424

    @Override
    public BlockBuilder appendStructure(Block block)
    {
        if (!(block instanceof SingleMapBlock)) {
            throw new IllegalArgumentException("Expected SingleMapBlock");
        }
        if (currentEntryOpened) {
            throw new IllegalStateException("Expected current entry to be closed but was opened");
        }
        currentEntryOpened = true;

        SingleMapBlock singleMapBlock = (SingleMapBlock) block;
        int blockPositionCount = singleMapBlock.getPositionCount();
        if (blockPositionCount % 2 != 0) {
            throw new IllegalArgumentException(format("block position count is not even: %s", blockPositionCount));
        }
        for (int i = 0; i < blockPositionCount; i += 2) {
            if (singleMapBlock.isNull(i)) {
                throw new IllegalArgumentException("Map keys must not be null");
            }
            else {
                singleMapBlock.writePositionTo(i, keyBlockBuilder);
            }
            if (singleMapBlock.isNull(i + 1)) {
                valueBlockBuilder.appendNull();
            }
            else {
                singleMapBlock.writePositionTo(i + 1, valueBlockBuilder);
            }
        }

        closeEntry(singleMapBlock.getHashTable(), singleMapBlock.getOffsetBase() / 2 * HASH_MULTIPLIER);
        return this;
    }

    @Override
    public BlockBuilder appendStructureInternal(Block block, int position)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Ensure the source map block never contains null keys before appending
  2. Filter or drop entries whose keys are null before building the map
  3. Validate with an IS NULL check on key positions in producing code

Example fix

// before
mapBlockBuilder.appendStructure(singleMapBlock);
// after
for (int i = 0; i < singleMapBlock.getPositionCount(); i += 2) {
    checkState(!singleMapBlock.isNull(i), "null key in source map");
}
mapBlockBuilder.appendStructure(singleMapBlock);
Defensive patterns

Strategy: validation

Validate before calling

for (int i = 0; i < singleMapBlock.getPositionCount(); i += 2) {
    if (singleMapBlock.isNull(i)) {
        throw new IllegalArgumentException("source map has null key at " + i);
    }
}

Try / catch

try {
    builder.appendStructure(singleMapBlock);
} catch (IllegalArgumentException e) {
    // rebuild map without null keys
}

Prevention

When it happens

Trigger: Calling MapBlockBuilder.appendStructure (or writeBlock/appendStructure paths) with a source singleMapBlock whose even positions (keys) contain a null at any key slot.

Common situations: Copying a deserialized or untrusted block built outside strict validation; test code constructing maps with null keys; data round-tripped from engines that allow null map keys.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/49318001ef4c3b7b. Report an issue: GitHub.