{"record":{"id":"442ba6e75a1f089a","repo":"apache/seatunnel","slug":"unable-to-convert-to-decimal-from-unexpected-value","errorCode":null,"errorMessage":"Unable to convert to decimal from unexpected value '${value}' of type ${value.getClass()}","messagePattern":"Unable to convert to decimal from unexpected value '(.+?)' of type (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-tidb/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/tidb/source/converter/DefaultDataConverter.java","lineNumber":218,"sourceCode":"        } else if (value instanceof Double) {\n            return ((Double) value).floatValue();\n        } else {\n            return Float.parseFloat(value.toString());\n        }\n    }\n\n    private static Object createDecimalConverter(Object value) {\n        BigDecimal result;\n        if (value instanceof String) {\n            result = new BigDecimal((String) value);\n        } else if (value instanceof Long) {\n            result = new BigDecimal(Long.parseLong(value.toString()));\n        } else if (value instanceof Double) {\n            result = BigDecimal.valueOf(Double.parseDouble(value.toString()));\n        } else if (value instanceof BigDecimal) {\n            result = (BigDecimal) value;\n        } else {\n            throw new IllegalArgumentException(\n                    \"Unable to convert to decimal from unexpected value '\"\n                            + value\n                            + \"' of type \"\n                            + value.getClass());\n        }\n        return result;\n    }\n\n    public Object[] convertToArray(Object value) throws SQLException {\n        String[] array = ((String) value).split(\",\");\n        if (array == null) {\n            return null;\n        }\n        return array;\n    }\n\n    private static Object convertToBinary(Object value) {\n        if (value instanceof byte[]) {","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-tidb/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/tidb/source/converter/DefaultDataConverter.java#L200-L236","documentation":"TiDB CDC's createDecimalConverter converts values to BigDecimal for DECIMAL columns and only accepts Long, Double, and BigDecimal inputs. Any other type (String, byte[], etc.) triggers an IllegalArgumentException naming the offending value and class.","triggerScenarios":"convert() meets a DECIMAL column whose runtime value is not Long/Double/BigDecimal — commonly a String from the TiKV puller or a java.lang.Byte/Short/Integer variant.","commonSituations":"Schema drift where TiDB column type changed from DECIMAL to VARCHAR but cached schema still says DECIMAL; TiDB CDC version emitting different value classes after an upgrade.","solutions":["Inspect the actual runtime type and extend/patch the converter branch to handle it (e.g. new BigDecimal(value.toString()) for Strings)","Ensure the SeaTunnel TiDB CDC row's schema matches the real TiDB column type","Align connector versions so TiDB CDC emits the expected numeric classes","Pre-coerce values in an upstream transform before they reach the converter"],"exampleFix":"// before\n} else {\n    throw new IllegalArgumentException(...);\n}\n// after\n} else if (value instanceof String) {\n    result = new BigDecimal((String) value);\n} else {\n    throw new IllegalArgumentException(...);\n}","handlingStrategy":"type-guard","validationCode":"static boolean isDecimalConvertible(Object v) {\n    return v instanceof Long || v instanceof Double || v instanceof BigDecimal;\n}","typeGuard":"static BigDecimal toDecimalSafe(Object v) {\n    if (v instanceof BigDecimal) return (BigDecimal) v;\n    if (v instanceof Long || v instanceof Double) return new BigDecimal(v.toString());\n    if (v instanceof String) return new BigDecimal((String) v);\n    return null; // caller decides to fail\n}","tryCatchPattern":"try {\n    return converter.convert(decimalType, value);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Decimal conversion failed for {} : {}\", value.getClass(), e.getMessage());\n    throw e;\n}","preventionTips":["Ensure TiDB column types match the SeaTunnel schema mapping","Add a String branch to the converter if TiDB CDC emits strings for decimals","Pin compatible connector and TiDB CDC versions"],"tags":["tidb","cdc","decimal","type-conversion"],"backgroundTag":"type-mismatch","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"}