apache/beam · error · TypeError

Only strings allowed as map keys when converting from AVRO,

Error message

Only strings allowed as map keys when converting from AVRO, found {beam_type}

What it means

avroio.avro_value_to_beam_value builds per-type converter lambdas from Avro dicts into Beam Row values. For Beam map types, Avro (JSON) maps may only have string keys; if the Beam schema's map_type.key_type is not STRING, the function raises TypeError because there is no valid Avro representation for non-string map keys.

Source

Thrown at sdks/python/apache_beam/io/avroio.py:666

          to_row)


def avro_value_to_beam_value(
    beam_type: schema_pb2.FieldType) -> Callable[[Any], Any]:
  type_info = beam_type.WhichOneof("type_info")
  if type_info == "atomic_type":
    return lambda value: value
  elif type_info == "array_type":
    element_converter = avro_value_to_beam_value(
        beam_type.array_type.element_type)
    return lambda value: [element_converter(e) for e in value]
  elif type_info == "iterable_type":
    element_converter = avro_value_to_beam_value(
        beam_type.iterable_type.element_type)
    return lambda value: [element_converter(e) for e in value]
  elif type_info == "map_type":
    if beam_type.map_type.key_type.atomic_type != schema_pb2.STRING:
      raise TypeError(
          f'Only strings allowed as map keys when converting from AVRO, '
          f'found {beam_type}')
    value_converter = avro_value_to_beam_value(beam_type.map_type.value_type)
    return lambda value: {k: value_converter(v) for (k, v) in value.items()}
  elif type_info == "row_type":
    converters = {
        field.name: avro_value_to_beam_value(field.type)
        for field in beam_type.row_type.schema.fields
    }
    return lambda value: beam.Row(
        **
        {name: convert(value[name])
         for (name, convert) in converters.items()})
  elif type_info == "logical_type":
    return lambda value: value
  else:
    raise ValueError(f"Unrecognized type_info: {type_info!r}")

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change the map key type to STRING in the Beam schema (schema_pb2.FieldType(atomic_type=STRING))
  2. Restructure the data as an array of rows with explicit key/value fields instead of a non-string map
  3. Convert at your own boundary: read the Avro dict, then Map to your desired typed structure manually instead of avro_dict_to_beam_row

Example fix

// before
field = schemas.schema_field('counts', schema_pb2.FieldType(map_type=schema_pb2.MapType(key_type=schema_pb2.FieldType(atomic_type=schema_pb2.INT64), value_type=...)))
// after
field = schemas.schema_field('counts', schema_pb2.FieldType(map_type=schema_pb2.MapType(key_type=schema_pb2.FieldType(atomic_type=schema_pb2.STRING), value_type=...)))
Defensive patterns

Strategy: validation

Validate before calling

from apache_beam.portability.api import schema_pb2
assert all(f.type.map_type.key_type.atomic_type == schema_pb2.STRING
           for f in beam_schema.fields if f.type.WhichOneof('type_info') == 'map_type')

Type guard

def has_string_map_keys(beam_type):
    return beam_type.WhichOneof('type_info') != 'map_type' or beam_type.map_type.key_type.atomic_type == schema_pb2.STRING

Try / catch

try:
    row = avroio.avro_dict_to_beam_row(avro_dict, beam_schema)
except TypeError as e:
    logging.error('map key conversion failed: %s', e)
    row = None  # restructure data as key/value rows instead

Prevention

When it happens

Trigger: Converting Avro data (avro_dict_to_beam_row or nested avro_value_to_beam_value) where the target Beam schema declares a map whose key type is INTEGER/BOOLEAN/etc. instead of STRING.

Common situations: Programmatically generated Beam schemas with non-string map keys being fed from Avro sources; building a Beam schema by hand that ignores Avro's key-type restriction; reading Avro with a schema derived elsewhere that used map<int, T>.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/4f3ed42ab368a410. Report an issue: GitHub.