apache/beam · error · TypeError

Only strings allowd as map keys when converting to JSON…

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.

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.

Appendix: 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)