tursodatabase/turso · error · java.sql.SQLException
ResultSet is null
Error message
ResultSet is null
What it means
get(int) requires a current row: lastStepResult must be non-null and its getResult() must be non-null. lastStepResult is only assigned inside next(), so this throw means a column was read before the first successful next() — the classic JDBC cursor-before-first-row misuse — or after a step that produced no row payload. It is a call-order bug, not an environment problem.
Solutions
- Always position the cursor first: if (rs.next()) { Object v = rs.get(1); }
- After TursoStatement.execute(), branch on its return value (or hasLastStepReturnedRow()) before reading columns
- Treat this error as a code bug to restructure, not a condition to catch and continue
Example fix
// before
boolean hasRow = stmt.execute();
Object v = rs.get(1); // throws when no row was stepped
// after
if (stmt.execute()) { // true: cursor sits on the first row
Object v = rs.get(1);
} Defensive patterns
Strategy: validation
Validate before calling
if (rs.next()) {
Object v = rs.get(1);
} else {
// no-row path
} Try / catch
try {
return rs.get(1);
} catch (SQLException e) {
// reading before next() is a call-order bug: fix the order, never catch-and-continue
throw new IllegalStateException("column read before next()", e);
} Prevention
- Always gate reads on next() == true (or execute()'s true return)
- For single-row lookups, write if (rs.next()) { ... } else { not-found } every time
- Treat 'ResultSet is null' as a logic bug, not a runtime condition to handle
When it happens
Trigger: Calling rs.get(...) immediately after prepare/execute without a next() that returned true; ignoring execute()'s boolean return (which reflects whether the internal single step produced a row) and reading unconditionally; reading after next() returned false.
Common situations: Code ported from APIs with auto-positioned or 0-based cursors; single-row lookups where the author assumes execute positions the cursor; missing if (rs.next()) guard around single-row reads.
Related errors
- column name not found
- columnIndex out of bound
- ResultSet closed
- ResultSet is not open
- step() returned invalid result
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/e57a8c21211be3e5.
Report an issue: GitHub.
Appendix: source
Thrown at bindings/java/src/main/java/tech/turso/core/TursoResultSet.java:165
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];
}
public String[] getColumnNames() {
return this.columnNames;
}
public void setColumnNames(String[] columnNames) {
this.columnNames = columnNames;
}
View on GitHub (pinned to 244cde92a7)