{"record":{"id":"216ef2e774f4f6b2","repo":"apache/seatunnel","slug":"avro-format-doesn-t-support-non-string-as-key-type","errorCode":null,"errorMessage":"Avro format doesn't support non-string as key type of map. The key type is: ${sqlType}","messagePattern":"Avro format doesn't support non-string as key type of map\\. The key type is: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-hudi/src/main/java/org/apache/seatunnel/connectors/seatunnel/hudi/sink/convert/AvroSchemaConverter.java","lineNumber":175,"sourceCode":"                Schema array =\n                        SchemaBuilder.builder()\n                                .array()\n                                .items(convertToSchema(arrayType.getElementType(), rowName, true));\n                return nullableSchema(array);\n            default:\n                throw new UnsupportedOperationException(\n                        \"Unsupported to derive Schema for type: \" + dataType);\n        }\n    }\n\n    public static SeaTunnelDataType<?> extractValueTypeToAvroMap(SeaTunnelDataType<?> type) {\n        SeaTunnelDataType<?> keyType;\n        SeaTunnelDataType<?> valueType;\n        MapType<?, ?> mapType = (MapType<?, ?>) type;\n        keyType = mapType.getKeyType();\n        valueType = mapType.getValueType();\n        if (keyType.getSqlType() != SqlType.STRING) {\n            throw new UnsupportedOperationException(\n                    \"Avro format doesn't support non-string as key type of map. \"\n                            + \"The key type is: \"\n                            + keyType.getSqlType());\n        }\n        return valueType;\n    }\n\n    /** Returns schema with nullable true. */\n    private static Schema nullableSchema(Schema schema) {\n        return Schema.createUnion(SchemaBuilder.builder().nullType(), schema);\n    }\n\n    private static int computeMinBytesForDecimalPrecision(int precision) {\n        int numBytes = 1;\n        while (Math.pow(2.0, 8 * numBytes - 1) < Math.pow(10.0, precision)) {\n            numBytes += 1;\n        }\n        return numBytes;","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-hudi/src/main/java/org/apache/seatunnel/connectors/seatunnel/hudi/sink/convert/AvroSchemaConverter.java#L157-L193","documentation":"Avro map schemas require string keys, so when extracting the value type for a MAP field, extractValueTypeToAvroMap() verifies the SeaTunnel map's key type is STRING. Any other key type throws UnsupportedOperationException with this message. Only the value type is returned for the Avro map item schema.","triggerScenarios":"A SeaTunnel schema containing a MapType whose keyType's SqlType is not STRING (e.g. MAP<INT,STRING> or MAP<LONG,...>) reaching the Hudi sink schema conversion.","commonSituations":"Sources with non-string-keyed maps (e.g. Protobuf map<uint32,string>, Parquet/Avro maps with integral keys) fed directly to the Hudi sink; assuming automatic key coercion.","solutions":["Transform the map so its keys are STRING (rebuild the map field with string keys in an upstream transform).","Serialize the map to a JSON string column before writing to Hudi.","If key semantics don't matter, drop the field before the sink."],"exampleFix":"// before\nMapType(INT, STRING) written to Hudi sink\n\n// after — convert to string-keyed map (or JSON string)\nMapType(STRING, STRING) written to Hudi sink","handlingStrategy":"validation","validationCode":"schema.toPhysicalRowDataType().getChildren().stream()\n    .filter(t -> t instanceof MapType)\n    .map(t -> (MapType<?, ?>) t)\n    .forEach(m -> {\n        if (m.getKeyType().getSqlType() != SqlType.STRING)\n            throw new IllegalArgumentException(\"map key must be STRING: \" + m);\n    });","typeGuard":"static boolean hasStringMapKeys(SeaTunnelDataType<?> t) {\n    return !(t instanceof MapType)\n        || ((MapType<?, ?>) t).getKeyType().getSqlType() == SqlType.STRING;\n}","tryCatchPattern":"try {\n    Schema s = AvroSchemaConverter.convertToSchema(rowType, \"rowName\");\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"non-string as key type of map\")) {\n        // rebuild the field with STRING keys or serialize to JSON\n    } else throw e;\n}","preventionTips":["Enforce STRING map keys in schema design for Hudi sinks.","Convert non-string-keyed maps at the source/transform layer.","Add a pre-flight schema check before writing MAP columns to Avro-backed tables."],"tags":["hudi","avro","map-type","unsupported-type","type-mapping"],"backgroundTag":"unsupported-dtype","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}