{"record":{"id":"ca53aa5a6a4ef78e","repo":"apache/beam","slug":"unexpected-null-for-key-type-fielddescriptor-getname","errorCode":null,"errorMessage":"Unexpected null for key type: \" + fieldDescriptor.getName()","messagePattern":"Unexpected null for key type: \" \\+ fieldDescriptor\\.getName\\(\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BeamRowToStorageApiProto.java","lineNumber":350,"sourceCode":"      case ROW:\n        return messageFromBeamRow(fieldDescriptor.getMessageType(), (Row) value, null, -1);\n      case ARRAY:\n      case ITERABLE:\n        Iterable<Object> iterable = (Iterable<Object>) value;\n        @Nullable FieldType iterableElementType = beamFieldType.getCollectionElementType();\n        if (iterableElementType == null) {\n          throw new RuntimeException(\"Unexpected null element type: \" + fieldDescriptor.getName());\n        }\n\n        return StreamSupport.stream(iterable.spliterator(), false)\n            .map(v -> toProtoValue(fieldDescriptor, iterableElementType, v))\n            .collect(Collectors.toList());\n      case MAP:\n        Map<Object, Object> map = (Map<Object, Object>) value;\n        @Nullable FieldType keyType = beamFieldType.getMapKeyType();\n        @Nullable FieldType valueType = beamFieldType.getMapValueType();\n        if (keyType == null) {\n          throw new RuntimeException(\"Unexpected null for key type: \" + fieldDescriptor.getName());\n        }\n        if (valueType == null) {\n          throw new RuntimeException(\n              \"Unexpected null for value type: \" + fieldDescriptor.getName());\n        }\n\n        return map.entrySet().stream()\n            .map(\n                (Map.Entry<Object, Object> entry) ->\n                    mapEntryToProtoValue(\n                        fieldDescriptor.getMessageType(), keyType, valueType, entry))\n            .collect(Collectors.toList());\n      default:\n        return scalarToProtoValue(fieldDescriptor, beamFieldType, value);\n    }\n  }\n\n  private static DynamicMessage buildTimestampPicosMessage(","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BeamRowToStorageApiProto.java#L332-L368","documentation":"For MAP-typed values in toProtoValue, the key and value FieldTypes are retrieved to convert each entry. A null key type means the map's FieldType lacks key-type metadata; since each BigQuery key/value struct entry needs both converters, the converter throws immediately, naming the proto field.","triggerScenarios":"toProtoValue case MAP where beamFieldType.getMapKeyType() returns null - i.e. the FieldType is TypeName.MAP but was not created with a key type (not via FieldType.map(k, v)).","commonSituations":"Row data carrying Map values whose schema field was assembled without key type; schema inference from raw Map types; schema evolution dropping map metadata.","solutions":["Rebuild the field with FieldType.map(keyType, valueType).","Use generic Map<K,V> fields in schema classes so inference records the key type.","Pre-validate: for each MAP field check getMapKeyType() != null before writing.","Catch and translate the RuntimeException to a schema-validation error for the offending field."],"exampleFix":"// before\nFieldType m = FieldType.builder().setType(TypeName.MAP).setMapValueType(FieldType.string()).build();\n// after\nFieldType m = FieldType.map(FieldType.string(), FieldType.string());","handlingStrategy":"validation","validationCode":"for (Schema.Field f : schema.getFields()) {\n  if (f.getType().getTypeName() == Schema.TypeName.MAP && f.getType().getMapKeyType() == null) {\n    throw new IllegalArgumentException(\"Field \" + f.getName() + \" missing map key type\");\n  }\n}","typeGuard":"boolean hasMapKeyType(Schema.Field f) {\n  return f.getType().getTypeName() != Schema.TypeName.MAP || f.getType().getMapKeyType() != null;\n}","tryCatchPattern":"try {\n  value = toProtoValue(fieldDescriptor, beamFieldType, v);\n} catch (RuntimeException e) {\n  if (e.getMessage().startsWith(\"Unexpected null for key type\")) {\n    throw new SchemaException(\"Map field lacks key type: \" + e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Always create map fields with FieldType.map(k, v)","Use generic Map<K,V> in record classes","Run schema completeness checks in CI"],"tags":["java","apache-beam","bigquery","map-type"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}