apache/iceberg · error · IllegalArgumentException
Cannot delete value type from map:
Error message
Cannot delete value type from map:
What it means
SchemaUpdate.applyChangesToMap attempts to look up the map's value field when applying a delete requirement to a map type. When the resolved value type is null (the value field does not exist in the resulting schema state), the update throws this IllegalArgumentException instead of silently producing an invalid schema. It protects the invariant that a map always has a key and value field.
Source
Thrown at core/src/main/java/org/apache/iceberg/SchemaUpdate.java:731
@Override
public Type map(Types.MapType map, Type kResult, Type valueResult) {
// if any updates are intended for the key, throw an exception
int keyId = map.fields().get(0).fieldId();
if (deletes.contains(keyId)) {
throw new IllegalArgumentException("Cannot delete map keys: " + map);
} else if (updates.containsKey(keyId)) {
throw new IllegalArgumentException("Cannot update map keys: " + map);
} else if (parentToAddedIds.containsKey(keyId)) {
throw new IllegalArgumentException("Cannot add fields to map keys: " + map);
} else if (!map.keyType().equals(kResult)) {
throw new IllegalArgumentException("Cannot alter map keys: " + map);
}
// use field to apply updates to the value
Types.NestedField valueField = map.fields().get(1);
Type valueType = field(valueField, valueResult);
if (valueType == null) {
throw new IllegalArgumentException("Cannot delete value type from map: " + map);
}
Types.NestedField valueUpdate = updates.get(valueField.fieldId());
boolean isValueOptional =
valueUpdate != null ? valueUpdate.isOptional() : map.isValueOptional();
if (isValueOptional == map.isValueOptional() && map.valueType() == valueType) {
return map;
}
if (isValueOptional) {
return Types.MapType.ofOptional(map.keyId(), map.valueId(), map.keyType(), valueType);
} else {
return Types.MapType.ofRequired(map.keyId(), map.valueId(), map.keyType(), valueType);
}
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Remove the delete requirement targeting the map value field ID, or instead require/delete the whole map column
- Use updateSchema().deleteColumn on the parent column, not the internal map value field
- Verify nested field IDs with table.schema().findField(...) before deleting
Example fix
// before
updateSchema.deleteColumn("events", 21); // 21 = map value field id
// after
updateSchema.deleteColumn("events"); // delete the map column itself Defensive patterns
Strategy: validation
Validate before calling
Types.NestedField valueField = map.fields().get(1);
if (schema.findField(valueField.fieldId()) == null) {
throw new IllegalArgumentException("Map value field " + valueField.fieldId() + " does not exist; delete the map column instead");
} Try / catch
try { update.apply(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Cannot delete value type from map")) { /* delete parent map column instead */ } else { throw e; } } Prevention
- Resolve nested field IDs via schema.findField before deleting
- Never delete internal map key/value field IDs directly; target the map column
- Validate updates with schema validation (UpdateSchema.apply) before commit
When it happens
Trigger: Calling UpdateSchema.delete on a map's value field ID (or a nested element that resolves to the map value), so that field(valueField, valueResult) returns null and no updates exist to redefine the value.
Common situations: Code that deletes columns by iterating all nested field IDs and accidentally includes map value field IDs; schema evolution scripts targeting the wrong nested ID after spec changes.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Field + field.name() + not found in source schema
- Provided schema:...Problems: (IllegalArgumentException with
- Cannot delete element type from list:
- Cannot delete map keys:
- Cannot update map keys:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/b689466f0305f4c8.
Report an issue: GitHub.