tursodatabase/turso · error · SQLException
Type conversion failed: {}
Error message
Type conversion failed: {} What it means
Every typed getter on JDBC4ResultSet (getString, getBoolean, getByte, getShort, getInt, getLong, getFloat, getDouble, getBigDecimal, getBytes, date/time getters, getCharacterStream) reads the raw Turso value and casts it directly: INTEGER arrives as Long, REAL as Double, TEXT as String, BLOB as byte[]. wrapTypeConversion wraps what the cast throws — usually ClassCastException — into SQLException("Type conversion failed: " + e). NULL is handled before the cast, so this error is always a storage-class/getter mismatch, never a null.
Source
Thrown at bindings/java/src/main/java/tech/turso/jdbc4/JDBC4ResultSet.java:1396
*
* @param <T> the type of value to supply
*/
@FunctionalInterface
public interface ResultSetSupplier<T> {
/**
* Gets a result from the result set.
*
* @return the result value
* @throws Exception if an error occurs
*/
T get() throws Exception;
}
private <T> T wrapTypeConversion(ResultSetSupplier<T> supplier) throws SQLException {
try {
return supplier.get();
} catch (Exception e) {
throw new SQLException("Type conversion failed: " + e);
}
}
}
View on GitHub (pinned to 244cde92a7)
Solutions
- Read each column with the getter that matches its storage class (INTEGER->getLong, REAL->getDouble, TEXT->getString, BLOB->getBytes)
- Normalize in SQL with CAST(col AS INTEGER) / CAST(col AS TEXT) so the driver receives the expected type
- Use rs.getObject(col), which performs no conversion, and convert yourself (instanceof on Long/Double/String/byte[])
- Fix the data so a column holds one storage class; use typeof(col) in SQL to find offending rows
Example fix
// before: column stores TEXT
int id = rs.getInt("id"); // SQLException: Type conversion failed
// after: cast in SQL, or read and parse
int id = stmt.executeQuery("SELECT CAST(id AS INTEGER) AS id FROM t")
.getInt("id");
// or
Object v = rs.getObject("id");
int id = v instanceof Number n ? n.intValue() : Integer.parseInt(v.toString()); Defensive patterns
Strategy: validation
Validate before calling
// getObject does no conversion: probe the storage class first
Object v = rs.getObject(col);
long id;
if (v instanceof Number n) {
id = n.longValue();
} else if (v != null) {
id = Long.parseLong(v.toString());
} else {
id = 0L; // NULL
} Type guard
private boolean readableAsLong(ResultSet rs, int col) throws SQLException {
Object v = rs.getObject(col);
return v == null || v instanceof Number;
} Try / catch
try {
return rs.getInt(col);
} catch (SQLException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Type conversion failed")) {
Object v = rs.getObject(col);
return v == null ? 0 : Integer.parseInt(v.toString()); // manual fallback
}
throw e;
} Prevention
- Match getters to storage classes: INTEGER->getLong, REAL->getDouble, TEXT->getString, BLOB->getBytes
- Use CAST(col AS ...) in the SELECT when a column's storage class does not match the reader you must use
- Do not treat rs.getString as a universal getter on this driver; it fails on INTEGER/REAL values
- Check typeof(col) in SQL when importing data to catch mixed-storage columns early
When it happens
Trigger: rs.getInt/getLong on a TEXT column, even when the text is '42' (the value is a String, the cast to Long fails); rs.getString on an INTEGER or REAL column (Long/Double cannot cast to String); getLong on a REAL column (Double to Long); getBoolean on non-INTEGER storage (the cast (Long) result); getBytes/getDate/getCharacterStream on a column that is not a BLOB/TEXT/TEXT respectively.
Common situations: Migrating from xerial sqlite-jdbc, which coerces lazily ('42' -> 42 works there but not here); reading CSV/imported data where everything landed as TEXT; using rs.getString(col) as a universal getter across mixed-type columns; ORM entity fields typed Long while the column stores REAL.
Related errors
- Exception while retrieving number of changes
- Exception while retrieving parameter count
- Exception while resetting statement
- turso only supports CLOSE_CURSORS_AT_COMMIT
- Savepoints are not supported by Turso
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/43c2d5c32f4cd715.
Report an issue: GitHub.