tursodatabase/turso · error · java.sql.SQLException
column name not found
Error message
column name {columnName} not found What it means
get(String columnName) performs a linear scan of the columnNames array using exact, case-sensitive equals(); if no element matches the argument it throws. There is no case-insensitive fallback and no metadata lookup, so the argument must match the SQL-produced name byte for byte — quoted identifiers keep their case and any whitespace.
Solutions
- Inspect rs.getColumnNames() and use the exact element returned
- Make both sides agree explicitly: alias in SQL (SELECT x AS name) and use that alias in code
- Resolve the index yourself case-insensitively from getColumnNames(), then call get(int)
- Switch to positional get(int) when column names are unstable
Example fix
// before
Object v = rs.get("UserName"); // column is 'username' -> throws
// after
String[] cols = rs.getColumnNames();
int idx = -1;
for (int i = 0; i < cols.length; i++) {
if (cols[i].equalsIgnoreCase("UserName")) { idx = i + 1; break; }
}
if (idx == -1) throw new IllegalArgumentException("no column 'UserName' in " + java.util.Arrays.toString(cols));
Object v = rs.get(idx); Defensive patterns
Strategy: validation
Validate before calling
String[] cols = rs.getColumnNames();
int idx = -1;
for (int i = 0; i < cols.length; i++) {
if (cols[i].equals(wanted) || cols[i].equalsIgnoreCase(wanted)) { idx = i + 1; break; }
}
if (idx == -1) {
throw new IllegalArgumentException(
"no column '" + wanted + "' in " + Arrays.toString(cols));
}
Object v = rs.get(idx); Try / catch
try {
return rs.get("username");
} catch (SQLException e) {
throw new IllegalArgumentException(
"unknown column; available: " + Arrays.toString(rs.getColumnNames()), e);
} Prevention
- Alias columns explicitly in SELECT (AS name) so SQL and reader agree
- For SELECT * result sets, resolve indexes once via getColumnNames(), then use get(int)
- Keep one constants class for column names shared by SQL text and readers
When it happens
Trigger: Requesting 'Name' when the query yields 'name'; using the table's column name when the SELECT list aliases it (SELECT x AS y); asking for a column not present in the SELECT list; requesting the table-qualified 't.id' when the result name is just 'id'.
Common situations: SELECT * with case differences between schema and reader constants; expression columns with engine-generated names; refactors renaming columns while reader code lags; whitespace in config-driven column names.
Related errors
- columnIndex out of bound
- ResultSet closed
- ResultSet is not open
- ResultSet is null
- step() returned invalid result
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/cf7b93beb99f14e7.
Report an issue: GitHub.
Appendix: source
Thrown at bindings/java/src/main/java/tech/turso/core/TursoResultSet.java:156
public void checkOpen() throws SQLException {
if (!open) {
throw new SQLException("ResultSet closed");
}
}
public void close() throws SQLException {
this.open = false;
}
public Object get(String columnName) throws SQLException {
final int columnsLength = this.columnNames.length;
for (int i = 0; i < columnsLength; i++) {
if (this.columnNames[i].equals(columnName)) {
return get(i + 1);
}
}
throw new SQLException("column name " + columnName + " not found");
}
public Object get(int columnIndex) throws SQLException {
if (!this.isOpen()) {
throw new SQLException("ResultSet is not open");
}
if (this.lastStepResult == null || this.lastStepResult.getResult() == null) {
throw new SQLException("ResultSet is null");
}
final Object[] resultSet = this.lastStepResult.getResult();
if (columnIndex > resultSet.length || columnIndex < 0) {
throw new SQLException("columnIndex out of bound");
}
return resultSet[columnIndex - 1];
}View on GitHub (pinned to 244cde92a7)