{"record":{"id":"91e1463d30565940","repo":"apache/iceberg","slug":"map-schema-should-have-both-key-and-value-ids-s","errorCode":null,"errorMessage":"Map schema {} should have both key and value ids set or both unset","messagePattern":"Map schema (.+?) should have both key and value ids set or both unset","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/avro/PruneColumns.java","lineNumber":155,"sourceCode":"      }\n      return union;\n    }\n\n    return null;\n  }\n\n  @Override\n  @SuppressWarnings(\"checkstyle:CyclomaticComplexity\")\n  public Schema array(Schema array, Schema element) {\n    if (array.getLogicalType() instanceof LogicalMap) {\n      Schema keyValue = array.getElementType();\n      Integer keyId =\n          AvroSchemaUtil.getFieldId(keyValue.getField(\"key\"), nameMapping, fieldNames());\n      Integer valueId =\n          AvroSchemaUtil.getFieldId(keyValue.getField(\"value\"), nameMapping, fieldNames());\n      if (keyId == null || valueId == null) {\n        if (keyId != null || valueId != null) {\n          LOG.warn(\"Map schema {} should have both key and value ids set or both unset\", array);\n        }\n        return null;\n      }\n\n      // if either key or value is selected, the whole map must be projected\n      if (selectedIds.contains(keyId) || selectedIds.contains(valueId)) {\n        return complexMapWithIds(array, keyId, valueId);\n      } else if (element != null) {\n        Schema.Field keyProjectionField = element.getField(\"key\");\n        Schema valueProjection = element.getField(\"value\").schema();\n        // it is possible that key is not selected, and\n        // key schemas can be different if new field ids were assigned to them\n        if (keyProjectionField != null\n            && !Objects.equals(keyValue.getField(\"key\").schema(), keyProjectionField.schema())) {\n          Preconditions.checkState(\n              SchemaNormalization.parsingFingerprint64(keyValue.getField(\"key\").schema())\n                  == SchemaNormalization.parsingFingerprint64(keyProjectionField.schema()),\n              \"Map keys should not be projected\");","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/avro/PruneColumns.java#L137-L173","documentation":"Avro PruneColumns warns when projecting an Avro array-of-record map representation where only one of the Avro 'key'/'value' fields resolves to a field ID via the name mapping. Iceberg requires both IDs present or both absent; a partial mapping means column pruning cannot safely project the map, so the field is pruned (returns null).","triggerScenarios":"Reading an Avro manifest/data file with a name mapping (schema.name-mapping.default) that maps the map's 'key' field but not 'value' (or vice versa) during schema pruning.","commonSituations":"Hand-written or partially generated name mappings; mappings created before a schema evolution added IDs; mappings missing nested entries for map key/value.","solutions":["Regenerate the name mapping so both 'key' and 'value' entries have field-ids (e.g. via MetricsUtil or createNameMapping).","Fix the existing mapping JSON to include matching key_id and value_id entries for the map.","Remove the stale mapping so reads fall back to full projection, or rewrite files with current metadata."],"exampleFix":"// before: mapping only has key\n[{\"field-id\": 2, \"names\": [\"m\"]}, {\"field-id\": 3, \"names\": [\"key\"]}]\n// after\n[{\"field-id\": 2, \"names\": [\"m\"]}, {\"field-id\": 3, \"names\": [\"key\"]}, {\"field-id\": 4, \"names\": [\"value\"]}]","handlingStrategy":"validation","validationCode":"// validate name mapping covers map key and value\nNameMapping mapping = ...;\nboolean complete = mapping != null; // regenerate via:\n// NameMappingParser.fromJson(Mapping.createNameMapping(table.schema()))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always generate name mappings from the table schema instead of writing them by hand.","Regenerate mappings after any schema evolution.","Include explicit key/value entries with field-ids for every map field."],"tags":["avro","name-mapping","schema-pruning"],"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-23T08:17:48.524Z"}