{"record":{"id":"77619d38bf38cd91","repo":"apache/iceberg","slug":"cannot-convert-to-bigdecimal-value-getclass-g","errorCode":null,"errorMessage":"Cannot convert to BigDecimal: ${value.getClass().getName()}","messagePattern":"Cannot convert to BigDecimal: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/RecordConverter.java","lineNumber":474,"sourceCode":"    throw new IllegalArgumentException(\"Cannot convert to double: \" + value.getClass().getName());\n  }\n\n  protected BigDecimal convertDecimal(Object value, DecimalType type) {\n    BigDecimal bigDecimal;\n    if (value instanceof BigDecimal) {\n      bigDecimal = (BigDecimal) value;\n    } else if (value instanceof Number) {\n      Number num = (Number) value;\n      Double dbl = num.doubleValue();\n      if (dbl.equals(Math.floor(dbl))) {\n        bigDecimal = BigDecimal.valueOf(num.longValue());\n      } else {\n        bigDecimal = BigDecimal.valueOf(dbl);\n      }\n    } else if (value instanceof String) {\n      bigDecimal = new BigDecimal((String) value);\n    } else {\n      throw new IllegalArgumentException(\n          \"Cannot convert to BigDecimal: \" + value.getClass().getName());\n    }\n    return bigDecimal.setScale(type.scale(), RoundingMode.HALF_UP);\n  }\n\n  protected boolean convertBoolean(Object value) {\n    if (value instanceof Boolean) {\n      return (boolean) value;\n    } else if (value instanceof String) {\n      return Boolean.parseBoolean((String) value);\n    }\n    throw new IllegalArgumentException(\"Cannot convert to boolean: \" + value.getClass().getName());\n  }\n\n  protected String convertString(Object value) {\n    try {\n      if (value instanceof String) {\n        return (String) value;","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/RecordConverter.java#L456-L492","documentation":"convertDecimal converts values to Iceberg DecimalType: it accepts BigDecimal, Number (via BigDecimal.valueOf), and String (new BigDecimal(String)). Any other class throws IllegalArgumentException naming the class. The result is then rescaled to the column's fixed scale with HALF_UP rounding.","triggerScenarios":"A field mapped to an Iceberg DecimalType column holding a Boolean, byte[], List, Map, or similar non-numeric non-string value.","commonSituations":"Decimal columns fed boolean or object JSON values; schemaless converters that wrap numbers in unexpected types; value objects from custom SMTs not unwrapped to numeric types.","solutions":["Emit numeric values (BigDecimal preferred to preserve precision) or decimal-parsable strings for decimal fields.","Change the Iceberg column type if the data is genuinely a different type.","Ensure the Connect converter/SMT doesn't wrap numbers in wrapper objects; unwrap before the sink.","Catch IllegalArgumentException and route bad records to a DLQ."],"exampleFix":"// before\nrecord.set(\"price\", true); // Boolean into DECIMAL(10,2)\n// after\nrecord.set(\"price\", new BigDecimal(\"9.99\"));","handlingStrategy":"validation","validationCode":"Object v = record.get(\"price\");\nif (!(v instanceof BigDecimal) && !(v instanceof Number) && !(v instanceof String)) {\n  throw new IllegalArgumentException(\"price must be decimal-compatible, got \" + v.getClass().getSimpleName());\n}","typeGuard":"boolean isDecimalConvertible(Object v) {\n  return v instanceof BigDecimal || v instanceof Number || v instanceof String;\n}","tryCatchPattern":"try {\n  sink.write(record);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Cannot convert to BigDecimal\")) {\n    sendToDlq(record, e);\n  } else throw e;\n}","preventionTips":["Prefer BigDecimal in producers for money fields to avoid precision loss from double conversion.","Confirm the Connect decimal converter is enabled so decimal logical types arrive as BigDecimal.","Check that string values parse as decimals before producing."],"tags":["kafka-connect","decimal","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"}