{"record":{"id":"b689466f0305f4c8","repo":"apache/iceberg","slug":"cannot-delete-value-type-from-map","errorCode":null,"errorMessage":"Cannot delete value type from map: ","messagePattern":"Cannot delete value type from map: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/SchemaUpdate.java","lineNumber":731,"sourceCode":"    @Override\n    public Type map(Types.MapType map, Type kResult, Type valueResult) {\n      // if any updates are intended for the key, throw an exception\n      int keyId = map.fields().get(0).fieldId();\n      if (deletes.contains(keyId)) {\n        throw new IllegalArgumentException(\"Cannot delete map keys: \" + map);\n      } else if (updates.containsKey(keyId)) {\n        throw new IllegalArgumentException(\"Cannot update map keys: \" + map);\n      } else if (parentToAddedIds.containsKey(keyId)) {\n        throw new IllegalArgumentException(\"Cannot add fields to map keys: \" + map);\n      } else if (!map.keyType().equals(kResult)) {\n        throw new IllegalArgumentException(\"Cannot alter map keys: \" + map);\n      }\n\n      // use field to apply updates to the value\n      Types.NestedField valueField = map.fields().get(1);\n      Type valueType = field(valueField, valueResult);\n      if (valueType == null) {\n        throw new IllegalArgumentException(\"Cannot delete value type from map: \" + map);\n      }\n\n      Types.NestedField valueUpdate = updates.get(valueField.fieldId());\n      boolean isValueOptional =\n          valueUpdate != null ? valueUpdate.isOptional() : map.isValueOptional();\n\n      if (isValueOptional == map.isValueOptional() && map.valueType() == valueType) {\n        return map;\n      }\n\n      if (isValueOptional) {\n        return Types.MapType.ofOptional(map.keyId(), map.valueId(), map.keyType(), valueType);\n      } else {\n        return Types.MapType.ofRequired(map.keyId(), map.valueId(), map.keyType(), valueType);\n      }\n    }\n\n    @Override","sourceCodeStart":713,"sourceCodeEnd":749,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SchemaUpdate.java#L713-L749","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nupdateSchema.deleteColumn(\"events\", 21); // 21 = map value field id\n// after\nupdateSchema.deleteColumn(\"events\"); // delete the map column itself","handlingStrategy":"validation","validationCode":"Types.NestedField valueField = map.fields().get(1);\nif (schema.findField(valueField.fieldId()) == null) {\n  throw new IllegalArgumentException(\"Map value field \" + valueField.fieldId() + \" does not exist; delete the map column instead\");\n}","typeGuard":null,"tryCatchPattern":"try { update.apply(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Cannot delete value type from map\")) { /* delete parent map column instead */ } else { throw e; } }","preventionTips":["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"],"tags":["schema","iceberg","schema-evolution"],"backgroundTag":"schema-validation-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}