apache/beam · error · IllegalArgumentException

Can't convert 'string' map keys to ${mapKeyType}

Error message

Can't convert 'string' map keys to ${mapKeyType}

What it means

Avro maps always have CharSequence (string) keys, and convertMapStrict converts them to a Beam MAP whose key type must be FieldType.STRING. If the target Beam FieldType declares any other map key type (e.g., INT64), the converter throws this IllegalArgumentException because strict conversion does not coerce string keys to another primitive type.

Source

Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java:1736

    for (Object value : values) {
      ret.add(
          convertAvroFieldStrict(value, elemAvroSchema, checkNotNull(elemFieldType), genericData));
    }

    return ret;
  }

  private static Object convertMapStrict(
      Map<CharSequence, Object> values,
      org.apache.avro.Schema valueAvroSchema,
      FieldType fieldType,
      GenericData genericData) {
    checkTypeName(fieldType.getTypeName(), TypeName.MAP, "map");
    FieldType mapKeyType = checkNotNull(fieldType.getMapKeyType());
    FieldType mapValueType = checkNotNull(fieldType.getMapValueType());

    if (!FieldType.STRING.equals(fieldType.getMapKeyType())) {
      throw new IllegalArgumentException(
          "Can't convert 'string' map keys to " + fieldType.getMapKeyType());
    }

    Map<Object, Object> ret = new HashMap<>();

    for (Map.Entry<CharSequence, Object> value : values.entrySet()) {
      ret.put(
          convertStringStrict(value.getKey(), mapKeyType),
          convertAvroFieldStrict(value.getValue(), valueAvroSchema, mapValueType, genericData));
    }

    return ret;
  }

  private static void checkTypeName(TypeName got, TypeName expected, String label) {
    checkArgument(
        got.equals(expected), "Can't convert '%s' to %s, expected: %s", label, got, expected);
  }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change the Beam FieldType map key to FieldType.STRING: FieldType.map(FieldType.STRING, valueType).
  2. Pre-transform the Avro record (MapElements) converting the map to a structure whose keys match the desired Beam type (e.g., an ARRAY of ROW(key,value) pairs).
  3. Use a logical type or iterate map entries manually instead of relying on strict conversion.

Example fix

// before
FieldType fieldType = FieldType.map(FieldType.INT64, FieldType.DOUBLE);
Object v = AvroUtils.convertAvroFieldStrict(record.get("m"), mapSchema, fieldType); // throws

// after
FieldType fieldType = FieldType.map(FieldType.STRING, FieldType.DOUBLE);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!FieldType.STRING.equals(fieldType.getMapKeyType())) {
  throw new IllegalStateException("Beam map key type must be STRING for Avro maps, got: "
      + fieldType.getMapKeyType());
}

Type guard

boolean avroCompatibleMap(FieldType t) {
  return t.getTypeName() == TypeName.MAP && FieldType.STRING.equals(t.getMapKeyType());
}

Try / catch

try {
  return AvroUtils.convertAvroFieldStrict(value, schema, fieldType);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Can't convert 'string' map keys")) {
    // convert map manually to STRING-keyed or ARRAY<ROW> structure
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling convertAvroFieldStrict on an Avro MAP schema value where the Beam FieldType was built with a non-STRING map key, e.g. FieldType.map(FieldType.INT64, valueType). Also triggered via toBeamRowStrict when a Beam schema field is map(K,V) with K != STRING while the Avro side is a map.

Common situations: Manually mapping an Avro map<string,int> to a Beam schema map<long,...> assuming keys can be parsed to numbers; generating a Beam schema from SQL or another source where map keys are numeric; copy-pasted schema definitions where the Avro key type was misremembered.

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