apache/beam · error · TypeError

Only strings allowd as map keys when converting to JSON, fou

Error message

Only strings allowd as map keys when converting to JSON, found {beam_type}

What it means

row_to_json converts Beam Rows to JSON-shaped values following a Beam schema. JSON objects only support string keys, so when a map-typed field's key type is not STRING, a TypeError is raised (message contains the typo 'allowd'). Non-string-keyed maps cannot be serialized to JSON.

Source

Thrown at sdks/python/apache_beam/yaml/json_utils.py:282

  def __getstate__(self):
    return {'_constructor': self._constructor, '_value': None}


def row_to_json(beam_type: schema_pb2.FieldType) -> Callable[[Any], Any]:
  """Returns a callable converting rows of the given type to Json objects."""
  type_info = beam_type.WhichOneof("type_info")
  if type_info == "atomic_type":
    return lambda value: value
  elif type_info == "array_type":
    element_converter = row_to_json(beam_type.array_type.element_type)
    return lambda value: [element_converter(e) for e in value]
  elif type_info == "iterable_type":
    element_converter = row_to_json(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 allowd as map keys when converting to JSON, '
          f'found {beam_type}')
    value_converter = row_to_json(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: row_to_json(field.type)
        for field in beam_type.row_type.schema.fields
    }
    return lambda row: {
        name: converted
        for (name, convert) in converters.items()
        # To filter out nullable fields in rows
        if (converted := convert(getattr(row, name, None))) is not None
    }
  elif type_info == "logical_type":
    return lambda value: value
  else:

View on GitHub (pinned to 12126d8942)

Solutions

  1. Convert map keys to strings before serialization (transform the row to use string keys)
  2. Change the schema so the map key_type is string
  3. Model the data as a repeated row of {key, value} fields instead of a map
  4. Emit to a format that supports non-string keys (Parquet/Avro) instead of JSON

Example fix

# before
schema: "map<integer, string> counts"
# after
schema: "array<row<key: string, value: string>> counts"
Defensive patterns

Strategy: validation

Validate before calling

from apache_beam.typehelp import schema_pb2
def assert_json_safe_rows(rows, beam_schema):
    for f in beam_schema.fields:
        t = f.type
        if t.WhichOneof('type_info') == 'map_type' and t.map_type.key_type.atomic_type != schema_pb2.STRING:
            raise TypeError(f'Field {f.name}: non-string map keys cannot be written as JSON')

Type guard

def is_json_safe_map(beam_type) -> bool:
    if beam_type.WhichOneof('type_info') != 'map_type':
        return True
    return beam_type.map_type.key_type.atomic_type == schema_pb2.STRING

Try / catch

try:
    out = json_formater(beam_schema, json_schema)(row)
except TypeError as e:
    raise TypeError(f'Stringify map keys or use a key/value row list: {e}') from e

Prevention

When it happens

Trigger: Writing Beam Rows whose schema has map<int, X> (or bytes/other key types) through row_to_json, json_formater, or row_validator, e.g. a yaml WriteToJson transform with a declared int-keyed map field.

Common situations: Source data (Avro/Parquet/Protobuf maps) with non-string keys being exported to JSON; schema inferred from such a source then used with a JSON sink in a yaml pipeline.

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/e099d49d0619c9ff. Report an issue: GitHub.