{"record":{"id":"ee6dc2b55f37822d","repo":"apache/beam","slug":"unexpected-null-element-type-for-the-map-s-key-on-field","errorCode":null,"errorMessage":"Unexpected null element type for the map's key on \" + field.getName()","messagePattern":"Unexpected null element type for the map's key on \" \\+ field\\.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":276,"sourceCode":"            throw new RuntimeException(\n                \"Unsupported precision for Timestamp logical type \" + precision);\n          }\n          // Map Timestamp.NANOS logical type to BigQuery TIMESTAMP(12) for nanosecond precision\n          type = TableFieldSchema.Type.TIMESTAMP;\n          builder.setTimestampPrecision(Int64Value.newBuilder().setValue(12L).build());\n        } else {\n          type = LOGICAL_TYPES.get(logicalType.getIdentifier());\n          if (type == null) {\n            throw new RuntimeException(\"Unsupported logical type \" + field.getType());\n          }\n        }\n        builder = builder.setType(type);\n        break;\n      case MAP:\n        @Nullable FieldType keyType = field.getType().getMapKeyType();\n        @Nullable FieldType valueType = field.getType().getMapValueType();\n        if (keyType == null) {\n          throw new RuntimeException(\n              \"Unexpected null element type for the map's key on \" + field.getName());\n        }\n        if (valueType == null) {\n          throw new RuntimeException(\n              \"Unexpected null element type for the map's value on \" + field.getName());\n        }\n\n        builder =\n            builder\n                .setType(TableFieldSchema.Type.STRUCT)\n                .addFields(fieldDescriptorFromBeamField(Field.of(\"key\", keyType)))\n                .addFields(fieldDescriptorFromBeamField(Field.of(\"value\", valueType)))\n                .setMode(TableFieldSchema.Mode.REPEATED);\n        break;\n      default:\n        @Nullable\n        TableFieldSchema.Type primitiveType = PRIMITIVE_TYPES.get(field.getType().getTypeName());\n        if (primitiveType == null) {","sourceCodeStart":258,"sourceCodeEnd":294,"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#L258-L294","documentation":"When converting a MAP-typed Beam field to a BigQuery STRUCT (BigQuery has no map type; maps become repeated structs of key/value), the converter reads the map's key type via FieldType.getMapKeyType(). A null key type means the FieldType is malformed or was constructed in a way that left the key type undefined, so no BigQuery mapping is possible.","triggerScenarios":"fieldDescriptorFromBeamField hitting case MAP where field.getType().getMapKeyType() returns null - i.e. a FieldType with TypeName.MAP that was not built via FieldType.map(keyType, valueType) or was mutated/deserialized incorrectly.","commonSituations":"Programmatically assembled schemas ( FieldType.builder().setType(TypeName.MAP) without a key type), schemas from custom format deserializers, or legacy serialized schemas where map metadata was lost.","solutions":["Build map fields with FieldType.map(keyType, valueType) so both key and value types are set.","Validate the schema up front: for every MAP field assert getMapKeyType() and getMapValueType() are non-null before calling the sink.","If the schema comes from another connector, re-declare it explicitly instead of reusing the inferred schema.","If null-ness is legitimately possible upstream, wrap conversion in try-catch and skip/fail the field with a clear message."],"exampleFix":"// before\nFieldType badMap = FieldType.builder().setType(TypeName.MAP).build();\n// after\nFieldType goodMap = FieldType.map(FieldType.string(), FieldType.int64());","handlingStrategy":"validation","validationCode":"schema.getFields().stream()\n  .filter(f -> f.getType().getTypeName() == Schema.TypeName.MAP)\n  .forEach(f -> {\n    if (f.getType().getMapKeyType() == null)\n      throw new IllegalArgumentException(\"Map field \" + f.getName() + \" missing key type\");\n  });","typeGuard":"boolean hasCompleteMapType(Schema.Field f) {\n  return f.getType().getTypeName() != Schema.TypeName.MAP\n      || (f.getType().getMapKeyType() != null && f.getType().getMapValueType() != null);\n}","tryCatchPattern":"try {\n  protoTableSchemaFromBeamSchema(schema);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"null element type for the map's key\")) {\n    throw new SchemaException(\"Malformed map field in schema: \" + e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Always use FieldType.map(k, v) factory methods","Avoid raw Map fields in @DefaultSchema record classes","Validate schemas in tests before running the pipeline"],"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"}