apache/seatunnel · error · java.lang.IllegalArgumentException

Map key cannot be null

Error message

Map key cannot be null

What it means

Arrow map keys cannot be null by definition. writeMapKey validates each key before writing it via the UnionMapWriter and throws IllegalArgumentException if a key entry is null. Null values are allowed, null keys are not.

Source

Thrown at seatunnel-connectors-v2/connector-lance/src/main/java/org/apache/seatunnel/connectors/seatunnel/lance/utils/FragmentConverter.java:183

    private static void writeListElement(
            UnionListWriter writer,
            ArrowType elementType,
            Object element,
            BufferAllocator allocator) {
        if (element == null) {
            writer.writeNull();
            return;
        }

        TypeWriter typeWriter = TypeWriterFactory.getWriter(elementType);
        typeWriter.writeToListWriter(writer, elementType, element, allocator);
    }

    private static void writeMapKey(
            UnionMapWriter writer, ArrowType keyType, Object key, BufferAllocator allocator) {
        if (key == null) {
            throw new IllegalArgumentException("Map key cannot be null");
        }

        TypeWriter typeWriter = TypeWriterFactory.getWriter(keyType);
        typeWriter.writeToMapKey(writer, keyType, key, allocator);
    }

    private static void writeMapValue(
            UnionMapWriter writer, ArrowType valueType, Object value, BufferAllocator allocator) {
        if (value == null) {
            writer.value().writeNull();
            return;
        }

        TypeWriter typeWriter = TypeWriterFactory.getWriter(valueType);
        typeWriter.writeToMapValue(writer, valueType, value, allocator);
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Clean the data upstream: remove or replace null keys before writing (e.g. map to a sentinel or skip)
  2. Convert the map to a TreeMap or filter entries with null keys
  3. If null keys are meaningful, change the column type (e.g. array of structs) instead of MAP
  4. Log the offending row to find the producing source

Example fix

// before
java.util.Map<Object,Object> raw = ...; // may contain null key
converter.setVectorValue(mapVector, field, raw, i, allocator); // throws
// after
java.util.Map<Object,Object> cleaned = new java.util.TreeMap<>();
raw.forEach((k, v) -> { if (k != null) cleaned.put(k, v); });
converter.setVectorValue(mapVector, field, cleaned, i, allocator);
Defensive patterns

Strategy: validation

Validate before calling

for (java.util.Map.Entry<?,?> e : ((java.util.Map<?,?>) value).entrySet()) {
    if (e.getKey() == null) {
        throw new IllegalArgumentException("Null map key in column " + field.getName());
    }
}

Type guard

boolean hasNoNullKeys(java.util.Map<?,?> m) {
    return m == null || !m.containsKey(null);
}

Try / catch

try {
    converter.setVectorValue(mapVector, field, value, rowIndex, allocator);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().equals("Map key cannot be null")) {
        LOG.warn("Row {} has a null map key in column {}; skipping entry", rowIndex, field.getName());
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: A java.util.Map being written contains a null key (e.g. HashMap allows one null key); writeMapToVector iterates entries and calls writeMapKey with key == null.

Common situations: Sources deserializing JSON with null object keys into a map; data from systems that permit null keys (HashMap, some NoSQL docs); missing key materialization after upstream joins or lookups.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/15b9231621d5aefa. Report an issue: GitHub.