{"record":{"id":"da2f46b492c66b20","repo":"apache/beam","slug":"only-strings-allowed-as-map-keys-when-converting-to-avro","errorCode":null,"errorMessage":"Only strings allowed as map keys when converting to AVRO, found {beam_type}","messagePattern":"Only strings allowed as map keys when converting to AVRO, found (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/avroio.py","lineNumber":732,"sourceCode":"  if type_info == \"atomic_type\":\n    avro_primitive = BEAM_PRIMITIVES_TO_AVRO_PRIMITIVES[beam_type.atomic_type]\n    avro_type = [\n        avro_primitive, 'null'\n    ] if beam_type.nullable else avro_primitive\n    return {'type': avro_type}\n  elif type_info == \"array_type\":\n    return {\n        'type': 'array',\n        'items': unnest_primitive_type(beam_type.array_type.element_type)\n    }\n  elif type_info == \"iterable_type\":\n    return {\n        'type': 'array',\n        'items': unnest_primitive_type(beam_type.iterable_type.element_type)\n    }\n  elif type_info == \"map_type\":\n    if beam_type.map_type.key_type.atomic_type != schema_pb2.STRING:\n      raise TypeError(\n          f'Only strings allowed as map keys when converting to AVRO, '\n          f'found {beam_type}')\n    return {\n        'type': 'map',\n        'values': unnest_primitive_type(beam_type.map_type.element_type)\n    }\n  elif type_info == \"row_type\":\n    return {\n        'type': 'record',\n        'name': beam_type.row_type.schema.id,\n        'fields': [{\n            'name': field.name, 'type': unnest_primitive_type(field.type)\n        } for field in beam_type.row_type.schema.fields],\n    }\n  else:\n    raise ValueError(f\"Unconvertable type: {beam_type}\")\n\n","sourceCodeStart":714,"sourceCodeEnd":750,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/avroio.py#L714-L750","documentation":"apache_beam raises this TypeError in beam_type_to_avro_type when a Beam Schema contains a map type whose key type is not the STRING atomic type. AVRO map keys must be strings, so any Beam map with non-string keys (e.g. int or bytes keys) cannot be represented in an AVRO schema. The check fires in the map_type branch while converting a Beam schema to an AVRO schema.","triggerScenarios":"Calling apache_beam.io.avroio.beam_schema_to_avro_schema() (directly or via AvroIO with schema generation) on a schema whose schema_pb2.Schema has a MAP field whose key_type.atomic_type is not STRING (e.g. map<int, str>).","commonSituations":"Pipelines that build Beam rows programmatically with non-string map keys and write them to AVRO sinks; schemas inferred from Python dicts with int keys; converting BigQuery/Parquet-derived schemas that allow non-string map keys to AVRO.","solutions":["Change the Beam schema so every map field uses string keys (coerce keys to str before writing).","Convert non-string-keyed maps to an ARRAY of ROW(key, value) fields, which AVRO can represent.","Write to a format that supports non-string map keys (e.g. Parquet) instead of AVRO.","Catch TypeError around the conversion and raise a clearer schema-design error at pipeline-construction time."],"exampleFix":"// before\nschema = beam.Row(m=beam.MapType[int, str])  # int keys\nWriteToAvro('out.avro', schema=schema)\n// after\nrow = beam.Row(m={str(k): v for k, v in my_int_keyed_map.items()})  # string keys\nWriteToAvro('out.avro', schema=beam.schema_from(row))","handlingStrategy":"validation","validationCode":"from apache_beam import schema_pb2\ndef validate_string_map_keys(schema: schema_pb2.Schema):\n    for f in schema.fields:\n        if f.type.type_info == schema_pb2.FieldType.MAP_TYPE and \\\n           f.type.map_type.key_type.atomic_type != schema_pb2.STRING:\n            raise ValueError(f\"Map field {f.name!r} must have string keys for AVRO\")","typeGuard":null,"tryCatchPattern":"try:\n    avro_schema = beam_schema_to_avro_schema(beam_schema)\nexcept TypeError as e:\n    if 'map keys' in str(e):\n        # coerce map keys or redesign field, then retry\n        ...\n    raise","preventionTips":["Keep Beam map fields string-keyed when the sink is AVRO","Model int-keyed maps as arrays of key/value rows","Validate schemas at pipeline construction time, before running"],"tags":["avro","beam-schema","type-mismatch","python"],"backgroundTag":"schema-validation-failed","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"}