{"record":{"id":"b728dd35af49169f","repo":"apache/iceberg","slug":"cannot-convert-to-variant-value-getclass-getn","errorCode":null,"errorMessage":"Cannot convert to variant: ${value.getClass().getName()}","messagePattern":"Cannot convert to variant: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/RecordConverter.java","lineNumber":670,"sourceCode":"      ValueArray array = Variants.array();\n      org.apache.kafka.connect.data.Schema elementSchema =\n          schema != null ? schema.valueSchema() : null;\n      for (Object element : collection) {\n        array.add(objectToVariantValue(element, metadata, elementSchema));\n      }\n      return array;\n    }\n    if (value instanceof Map<?, ?> map) {\n      return mapToVariantValue(map, metadata, schema);\n    }\n    if (value instanceof Struct struct) {\n      ShreddedObject object = Variants.object(metadata);\n      for (Field field : struct.schema().fields()) {\n        object.put(field.name(), objectToVariantValue(struct.get(field), metadata, field.schema()));\n      }\n      return object;\n    }\n    throw new IllegalArgumentException(\"Cannot convert to variant: \" + value.getClass().getName());\n  }\n\n  /** Converts a Map to VariantValue; throw IllegalArgumentException if the key is not a string. */\n  private static VariantValue mapToVariantValue(\n      Map<?, ?> map, VariantMetadata metadata, org.apache.kafka.connect.data.Schema schema) {\n    ShreddedObject object = Variants.object(metadata);\n    org.apache.kafka.connect.data.Schema mapValueSchema =\n        schema != null ? schema.valueSchema() : null;\n    map.forEach(\n        (key, val) -> {\n          if (key instanceof String keyStr) {\n            object.put(keyStr, objectToVariantValue(val, metadata, mapValueSchema));\n          } else {\n            throw new IllegalArgumentException(\n                \"Cannot convert map to variant: keys must be non-null strings, was: \"\n                    + (key == null ? \"null\" : key.getClass().getName()));\n          }\n        });","sourceCodeStart":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/RecordConverter.java#L652-L688","documentation":"objectToVariantValue throws this IllegalArgumentException when a value destined for an Iceberg Variant column is of an unrecognized Java type. Supported inputs are primitives, CharSequence, byte arrays/ByteBuffer, BigDecimal, temporal types, Struct, and Map; anything else (or null-typed containers it cannot interpret) fails.","triggerScenarios":"A Variant field receives a custom domain object, an array/List not wrapped as expected, or some type produced by an SMT that the converter has no branch for.","commonSituations":"Custom SMTs output exotic types (e.g. Guava objects, custom Avro wrappers); schema-less JSON arrives as JsonNode-like objects; version upgrade introduced a new Variant conversion path the payload doesn't match.","solutions":["Pre-transform the value into a supported type (String, Number, byte[], Map, Struct) in an SMT","Log the offending class from the message and add an explicit conversion branch in a RecordConverter subclass","Fix the producer to emit JSON/Avro values that map to standard Connect types","If the field is not meant to be a Variant, correct the table schema or field mapping"],"exampleFix":"// before\nvalue = new com.fasterxml.jackson.databind.JsonNode(...) // unsupported class\n// after\nvalue = jsonNode.toString() // or convert to Map<String,Object> first","handlingStrategy":"type-guard","validationCode":"static boolean isVariantCompatible(Object v) {\n  return v == null || v instanceof Boolean || v instanceof Number || v instanceof CharSequence\n      || v instanceof byte[] || v instanceof ByteBuffer || v instanceof java.math.BigDecimal\n      || v instanceof java.time.temporal.Temporal || v instanceof Map || v instanceof Struct;\n}","typeGuard":"static void requireVariantCompatible(Object v) {\n  if (v != null && !isVariantCompatible(v)) {\n    throw new IllegalStateException(\"Unsupported variant type: \" + v.getClass());\n  }\n}","tryCatchPattern":"try {\n  converter.convertValue(value, Types.VariantType.get());\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Cannot convert to variant:\")) {\n    log.error(\"Unsupported variant input class\", e);\n    // fallback: serialize value to JSON string and store as string variant\n  }\n}","preventionTips":["Restrict SMT outputs to standard Connect types","Avoid passing framework-specific wrappers (JsonNode, custom Number subclasses)","Document supported variant input types for producers","Add contract tests for variant payloads end to end"],"tags":["kafka-connect","variant","unsupported-type"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}