tursodatabase/turso · error · java.sql.SQLException

columnIndex out of bound

Error message

columnIndex out of bound

What it means

get(int) validates the 1-based columnIndex against the current row array and throws when it exceeds resultSet.length or is negative. Note the guard tests columnIndex < 0, not < 1: index 0 passes validation and then crashes with a raw ArrayIndexOutOfBoundsException at resultSet[columnIndex - 1], i.e. resultSet[-1]. So this specific SQLException means 'too large or negative', while 0-based misuse crashes differently — the operative rule is that JDBC column indexes start at 1.

Solutions

  1. Use 1-based indexes: the first column is get(1)
  2. Derive the bound from rs.getColumnNames().length and validate before calling
  3. Prefer get(String) with explicit SQL aliases when column order can shift

Example fix

// before
Object id = rs.get(0);                              // ArrayIndexOutOfBoundsException
Object name = rs.get(rs.getColumnNames().length + 1); // 'columnIndex out of bound'

// after
int cols = rs.getColumnNames().length; // 1-based: columns are get(1)..get(cols)
for (int i = 1; i <= cols; i++) {
  Object v = rs.get(i);
}
Defensive patterns

Strategy: validation

Validate before calling

int columnCount = rs.getColumnNames().length;
if (columnIndex < 1 || columnIndex > columnCount) {
  throw new IllegalArgumentException("columnIndex must be 1.." + columnCount);
}
Object v = rs.get(columnIndex);

Try / catch

try {
  return rs.get(columnIndex);
} catch (SQLException | ArrayIndexOutOfBoundsException e) {
  // note: get(0) crashes with ArrayIndexOutOfBoundsException, not this SQLException
  throw new IllegalArgumentException("columnIndex " + columnIndex + " out of range", e);
}

Prevention

When it happens

Trigger: Calling get(n + 1) where n is the column count; hardcoded indexes after the SELECT list changed; computed indexes going negative; passing get(0), which instead surfaces as ArrayIndexOutOfBoundsException.

Common situations: Converting code from 0-based APIs (JSON objects, CSV readers, arrays); SELECT lists edited without updating index constants; loops using <= instead of < against a 0-based length.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/6fbf46e14961c081. Report an issue: GitHub.

Appendix: source

Thrown at bindings/java/src/main/java/tech/turso/core/TursoResultSet.java:170

        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;
  }

  @Override
  public String toString() {
    return ("tursoResultSet{"
        + "statement="
        + statement

View on GitHub (pinned to 244cde92a7)