prestodb/presto · error · PrestoException

GENERIC_INTERNAL_ERROR

GENERIC_INTERNAL_ERROR

Error message

Map must never contain null keys

What it means

Text MapEncoding serializes maps as delimited text and has no way to represent a null key. A null key violates Presto's map invariant, so encodeValueInto throws PrestoException(GENERIC_INTERNAL_ERROR) rather than silently emitting malformed text.

Source

Thrown at presto-rcfile/src/main/java/com/facebook/presto/rcfile/text/MapEncoding.java:53

            TextColumnEncoding valueEncoding)
    {
        super(type, nullSequence, separators, escapeByte);
        this.keyEncoding = keyEncoding;
        this.valueEncoding = valueEncoding;
    }

    @Override
    public void encodeValueInto(int depth, Block block, int position, SliceOutput output)
            throws RcFileCorruptionException
    {
        byte elementSeparator = getSeparator(depth);
        byte keyValueSeparator = getSeparator(depth + 1);

        Block map = block.getBlock(position);
        boolean first = true;
        for (int elementIndex = 0; elementIndex < map.getPositionCount(); elementIndex += 2) {
            if (map.isNull(elementIndex)) {
                throw new PrestoException(StandardErrorCode.GENERIC_INTERNAL_ERROR, "Map must never contain null keys");
            }

            if (!first) {
                output.writeByte(elementSeparator);
            }
            first = false;
            keyEncoding.encodeValueInto(depth + 2, map, elementIndex, output);
            output.writeByte(keyValueSeparator);
            if (map.isNull(elementIndex + 1)) {
                output.writeBytes(nullSequence);
            }
            else {
                valueEncoding.encodeValueInto(depth + 2, map, elementIndex + 1, output);
            }
        }
    }

    @Override

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Fix the block producer to reject or replace null keys before encoding
  2. Add an upstream guard that filters null keys from the map (e.g. transform/filter block construction)
  3. Re-express the map in SQL with map_filter to drop null keys
  4. Catch PrestoException(GENERIC_INTERNAL_ERROR) and file a bug against the producing component

Example fix

// before
map.put(null, v);
// after
if (key != null) { map.put(key, v); } // or map_filter(m, (k, v) -> k IS NOT NULL)
Defensive patterns

Strategy: validation

Validate before calling

// before text-encoding a nested map
Block map = block.getBlock(position);
for (int i = 0; i < map.getPositionCount(); i += 2) {
    if (map.isNull(i)) { throw new IllegalArgumentException("null map key at " + i); }
}

Try / catch

try { stringMapEncoding.encodeValueInto(depth, block, position, output); }
catch (PrestoException e) {
    if (e.getErrorCode().getCode() == StandardErrorCode.GENERIC_INTERNAL_ERROR.toErrorCode().getCode()) {
        reportBug(e); // producer built a map with a null key
    } else { throw e; }
}

Prevention

When it happens

Trigger: encodeValueInto iterating a map Block where position elementIndex (a key slot, even index) isNull — only possible from a non-conforming MapBlock producer (connector, UDF, extension code).

Common situations: Custom connectors or UDFs constructing map blocks with null keys; bugs in block-building extension code; unit-test fixtures violating the map contract.

Related errors


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