tursodatabase/turso · error · SQLException

columnIndex out of bound

Error message

columnIndex out of bound

What it means

get(int) validates the JDBC 1-based index: it throws for columnIndex greater than the row's column count or negative values. Note an off-by-one hole in the guard: it tests columnIndex < 0, so 0 slips through and reaches resultSet[columnIndex - 1], surfacing as ArrayIndexOutOfBoundsException (index -1) instead of this SQLException — a classic 0-based-index mistake signature.

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 bad083fafb)

Solutions

  1. Use 1-based indices — the first column is 1
  2. Derive bounds from rs.getColumnNames().length instead of hardcoding
  3. Prefer get(String) with explicit aliases when the schema may change
  4. Loop with for (int i = 1; i <= rs.getColumnNames().length; i++)

Example fix

// before
for (int i = 0; i < 3; i++) rs.get(i); // get(0) -> ArrayIndexOutOfBounds; get(3) -> out of bound

// after
String[] cols = rs.getColumnNames();
for (int i = 1; i <= cols.length; i++) {
  Object v = rs.get(i);
}
Defensive patterns

Strategy: validation

Validate before calling

int n = rs.getColumnNames().length;
if (columnIndex >= 1 && columnIndex <= n) {
  Object v = rs.get(columnIndex);
}

Type guard

static boolean isValidColumnIndex(TursoResultSet rs, int columnIndex) {
  return columnIndex >= 1 && columnIndex <= rs.getColumnNames().length;
}

Prevention

When it happens

Trigger: get(4) on a 3-column result; hardcoded indices left stale after the SELECT list changed; negative indices from computed lookups; get(0) from 0-based habits (produces ArrayIndexOutOfBoundsException, not this message).

Common situations: Developers used to 0-based arrays writing rs.get(0); loops starting at 0; SELECT list edited (column removed) while index-based reads unchanged; mixing ordinal and name-based access during refactors.

Related errors


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