tursodatabase/turso · error · SQLException
column name " + columnName + " not found
Error message
column name " + columnName + " not found
What it means
get(String columnName) does a case-sensitive linear scan over the column names returned by the native columns() call and throws when no entry equals the given name exactly. Names are whatever the engine reports for the select list — including aliases and, for bare expressions, the expression text.
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 bad083fafb)
Solutions
- Print or inspect rs.getColumnNames() and use the exact reported label
- Add explicit AS aliases in the SELECT list and access by those aliases
- Fall back to 1-based ordinal access get(i)
- For tolerant lookup, resolve the index yourself from getColumnNames() (e.g. case-insensitively) and call get(int)
Example fix
// before
Object v = rs.get("userId"); // actual label is "userid" -> throws
// after
// SELECT id AS userId FROM t
Object v = rs.get("userId"); // alias matches exactly
// or resolve defensively:
String[] cols = rs.getColumnNames();
for (int i = 0; i < cols.length; i++) {
if (cols[i].equalsIgnoreCase("userId")) { v = rs.get(i + 1); break; }
} 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].equalsIgnoreCase(columnName)) { idx = i; break; }
}
if (idx < 0) {
throw new IllegalArgumentException(
"no column " + columnName + " in " + java.util.Arrays.toString(cols));
}
Object v = rs.get(idx + 1); Type guard
static boolean hasColumn(TursoResultSet rs, String columnName) {
for (String c : rs.getColumnNames()) {
if (c.equals(columnName)) return true;
}
return false;
} Prevention
- Alias every output column in the SELECT list and access by those exact aliases
- Log rs.getColumnNames() once when a query is first wired up
- Remember the lookup is case-sensitive — match the SQL label character for character
When it happens
Trigger: get("userId") when the label is "userid" or "USERID"; querying SELECT u.name AS user_name but asking for "name"; unaliased expressions (SELECT COUNT(*) reports a synthesized label); accessing a column dropped in a schema change; names with stray whitespace from config files.
Common situations: Joins with aliases where the code uses the original column name; ORMs mapping Java field names (camelCase) onto unaliased SQL columns; schema migrations renaming columns without updating readers; duplicate column names where only the first index matches.
Related errors
- columnIndex out of bound
- SQLite only supports TYPE_FORWARD_ONLY cursors
- SQLite only supports CONCUR_READ_ONLY cursors
- SQLite only supports closing cursors at commit
- The result set is not open
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/5c5e81bb33910089.
Report an issue: GitHub.