tursodatabase/turso · error · SQLException

Exception while retrieving parameter count

Error message

Exception while retrieving parameter count

What it means

Thrown when the native parameterCount call returns -1. In the native layer, -1 is only produced when the statement pointer cannot be resolved to a live statement; a live statement always returns its actual placeholder count. Hitting this means the statement was already closed, finalized, or its native handle is stale.

Source

Thrown at bindings/java/src/main/java/tech/turso/core/TursoStatement.java:285

    if (result == -1) {
      throw new SQLException("Exception while retrieving number of changes");
    }

    return result;
  }

  private native long changes(long statementPointer) throws SQLException;

  /**
   * Returns the number of parameters in this statement. Parameters are the `?`'s that get replaced
   * by the provided arguments.
   *
   * @throws SQLException If a database access error occurs
   */
  public int parameterCount() throws SQLException {
    final int result = parameterCount(statementPointer);
    if (result == -1) {
      throw new SQLException("Exception while retrieving parameter count");
    }

    return result;
  }

  private native int parameterCount(long statementPointer) throws SQLException;

  /** Resets this statement so it's ready for re-execution */
  public void reset() throws SQLException {
    final int result = reset(statementPointer);
    if (result == -1) {
      throw new SQLException("Exception while resetting statement");
    }
    this.resultSet = TursoResultSet.of(this);
  }

  private native int reset(long statementPointer) throws SQLException;

View on GitHub (pinned to bad083fafb)

Solutions

  1. Query parameterCount() right after preparing the statement and cache the value.
  2. Check isClosed() before calling when the statement's lifecycle is uncertain.
  3. Re-prepare the statement instead of resurrecting a closed one.
  4. Bind positions against the cached count rather than re-querying it after execution.

Example fix

// before
TursoStatement stmt = conn.prepare(sql);
stmt.close();
int params = stmt.parameterCount(); // throws: statement closed

// after
TursoStatement stmt = conn.prepare(sql);
int params = stmt.parameterCount(); // capture immediately after prepare
stmt.close();
Defensive patterns

Strategy: validation

Validate before calling

if (!stmt.isClosed()) {
    int params = stmt.parameterCount();
} else {
    throw new IllegalStateException("cannot query parameterCount on closed statement");
}

Try / catch

try {
    paramCount = stmt.parameterCount();
} catch (SQLException e) {
    throw new IllegalStateException("statement no longer open", e);
}

Prevention

When it happens

Trigger: Calling stmt.parameterCount() after close(); on a statement whose connection is closed; from code that holds a statement across requests after a pool recycled it.

Common situations: Validation helpers that count parameters late in a request lifecycle; retry logic that revalidates a cached statement after an error already closed it; middleware that inspects statements during shutdown.

Related errors


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