{"record":{"id":"abb635ea1f089f71","repo":"apache/iceberg","slug":"cannot-convert-to-string-value-getclass-getna","errorCode":null,"errorMessage":"Cannot convert to string: ${value.getClass().getName()}","messagePattern":"Cannot convert to string: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/RecordConverter.java","lineNumber":505,"sourceCode":"  }\n\n  protected String convertString(Object value) {\n    try {\n      if (value instanceof String) {\n        return (String) value;\n      } else if (value instanceof Number || value instanceof Boolean) {\n        return value.toString();\n      } else if (value instanceof Map || value instanceof List) {\n        return MAPPER.writeValueAsString(value);\n      } else if (value instanceof Struct) {\n        Struct struct = (Struct) value;\n        byte[] data = config.jsonConverter().fromConnectData(null, struct.schema(), struct);\n        return new String(data, StandardCharsets.UTF_8);\n      }\n    } catch (IOException e) {\n      throw new UncheckedIOException(e);\n    }\n    throw new IllegalArgumentException(\"Cannot convert to string: \" + value.getClass().getName());\n  }\n\n  protected Object convertUUID(Object value) {\n    UUID uuid;\n    if (value instanceof String) {\n      uuid = UUID.fromString((String) value);\n    } else if (value instanceof UUID) {\n      uuid = (UUID) value;\n    } else {\n      throw new IllegalArgumentException(\"Cannot convert to UUID: \" + value.getClass().getName());\n    }\n\n    if (FileFormat.PARQUET\n        .name()\n        .toLowerCase(Locale.ROOT)\n        .equals(config.writeProps().get(TableProperties.DEFAULT_FILE_FORMAT))) {\n      return UUIDUtil.convert(uuid);\n    } else {","sourceCodeStart":487,"sourceCodeEnd":523,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/RecordConverter.java#L487-L523","documentation":"convertString converts values to Iceberg StringType: it accepts String directly and Connect Struct (serialized to JSON via the configured JsonConverter); try/catch also allows other values where String.valueOf would work. If the value is neither a String nor a Struct (and the surrounding conversions don't apply), it throws IllegalArgumentException naming the class.","triggerScenarios":"A field mapped to an Iceberg StringType column holding a value type not handled by the try-block coercion — e.g. a raw byte[] or Map/List that the string conversion path rejects.","commonSituations":"String columns receiving structured values from schemaless JSON; producers emitting binary payloads into string columns; nested maps landing in string columns after table schema drift.","solutions":["Emit String values for string-typed columns, or wrap structured data in a Struct so it is JSON-serialized.","Change the Iceberg column type to match the actual value type (e.g. MapType or a struct).","Add an SMT (e.g. ValueToKey/Cast) to coerce the value to string before the sink.","Catch IllegalArgumentException and route the record to a DLQ."],"exampleFix":"// before\nrecord.set(\"meta\", Map.of(\"k\", \"v\")); // Map into StringType\n// after\nrecord.set(\"meta\", \"{\\\"k\\\":\\\"v\\\"}\"); // pre-serialized JSON string, or use a JSON-typed/VARIANT column","handlingStrategy":"validation","validationCode":"Object v = record.get(\"meta\");\nif (!(v instanceof String) && !(v instanceof Struct)) {\n  throw new IllegalArgumentException(\"meta must be String or Struct, got \" + v.getClass().getSimpleName());\n}","typeGuard":"boolean isStringConvertible(Object v) {\n  return v instanceof String || v instanceof Struct;\n}","tryCatchPattern":"try {\n  sink.write(record);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Cannot convert to string\")) {\n    sendToDlq(record, e);\n  } else throw e;\n}","preventionTips":["Serialize structured payloads to JSON strings at the producer if the column is STRING.","Consider Iceberg VARIANT/struct columns instead of stuffing objects into string fields.","Ensure byte[] payloads are base64/UTF-8 encoded before sending to string columns."],"tags":["kafka-connect","string","type-coercion"],"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"}