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
- Change the Beam FieldType map key to FieldType.STRING: FieldType.map(FieldType.STRING, valueType).
- 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).
- 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
- Remember Avro map keys are always strings; never declare non-STRING map keys in Beam schemas fed by Avro.
- Model non-string keys as ARRAY<ROW<key,value>> instead of MAP.
- Generate Beam schemas from Avro schemas programmatically to avoid transcription errors.
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
- Avro only supports maps with string keys
- Can't convert 'null' to FieldType
- Unhandled logical type ${identifier}
- Unexpected type ${fieldType}
- Can't convert 'null' to non-nullable field
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9c77856aeb7023a8.
Report an issue: GitHub.