{"record":{"id":"9c77856aeb7023a8","repo":"apache/beam","slug":"can-t-convert-string-map-keys-to-mapkeytype","errorCode":null,"errorMessage":"Can't convert 'string' map keys to ${mapKeyType}","messagePattern":"Can't convert 'string' map keys to (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java","lineNumber":1736,"sourceCode":"    for (Object value : values) {\n      ret.add(\n          convertAvroFieldStrict(value, elemAvroSchema, checkNotNull(elemFieldType), genericData));\n    }\n\n    return ret;\n  }\n\n  private static Object convertMapStrict(\n      Map<CharSequence, Object> values,\n      org.apache.avro.Schema valueAvroSchema,\n      FieldType fieldType,\n      GenericData genericData) {\n    checkTypeName(fieldType.getTypeName(), TypeName.MAP, \"map\");\n    FieldType mapKeyType = checkNotNull(fieldType.getMapKeyType());\n    FieldType mapValueType = checkNotNull(fieldType.getMapValueType());\n\n    if (!FieldType.STRING.equals(fieldType.getMapKeyType())) {\n      throw new IllegalArgumentException(\n          \"Can't convert 'string' map keys to \" + fieldType.getMapKeyType());\n    }\n\n    Map<Object, Object> ret = new HashMap<>();\n\n    for (Map.Entry<CharSequence, Object> value : values.entrySet()) {\n      ret.put(\n          convertStringStrict(value.getKey(), mapKeyType),\n          convertAvroFieldStrict(value.getValue(), valueAvroSchema, mapValueType, genericData));\n    }\n\n    return ret;\n  }\n\n  private static void checkTypeName(TypeName got, TypeName expected, String label) {\n    checkArgument(\n        got.equals(expected), \"Can't convert '%s' to %s, expected: %s\", label, got, expected);\n  }","sourceCodeStart":1718,"sourceCodeEnd":1754,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java#L1718-L1754","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nFieldType fieldType = FieldType.map(FieldType.INT64, FieldType.DOUBLE);\nObject v = AvroUtils.convertAvroFieldStrict(record.get(\"m\"), mapSchema, fieldType); // throws\n\n// after\nFieldType fieldType = FieldType.map(FieldType.STRING, FieldType.DOUBLE);","handlingStrategy":"type-guard","validationCode":"if (!FieldType.STRING.equals(fieldType.getMapKeyType())) {\n  throw new IllegalStateException(\"Beam map key type must be STRING for Avro maps, got: \"\n      + fieldType.getMapKeyType());\n}","typeGuard":"boolean avroCompatibleMap(FieldType t) {\n  return t.getTypeName() == TypeName.MAP && FieldType.STRING.equals(t.getMapKeyType());\n}","tryCatchPattern":"try {\n  return AvroUtils.convertAvroFieldStrict(value, schema, fieldType);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Can't convert 'string' map keys\")) {\n    // convert map manually to STRING-keyed or ARRAY<ROW> structure\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["avro","beam","map","type-mismatch","schema-conversion"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}