prestodb/presto · error · SQLException
Parameter index out of bounds:
Error message
Parameter index out of bounds:
What it means
setParameter is the internal choke point for all setXxx calls; it rejects parameter indexes below 1 because JDBC parameter indexes are 1-based. Throwing means a setNull/setBoolean/setByte/setShort/setInt/setLong (or any other setter routed through it) was called with a non-positive index. No value is stored, so the statement is still usable after correcting the index.
Source
Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoPreparedStatement.java:799
@Override
public boolean execute(String sql, String[] columnNames)
throws SQLException
{
throw new SQLException("This method cannot be called on PreparedStatement");
}
@Override
public void addBatch(String sql)
throws SQLException
{
throw new SQLException("This method cannot be called on PreparedStatement");
}
private void setParameter(int parameterIndex, String value)
throws SQLException
{
if (parameterIndex < 1) {
throw new SQLException("Parameter index out of bounds: " + parameterIndex);
}
parameters.put(parameterIndex - 1, value);
}
private static List<String> toValues(Map<Integer, String> parameters)
throws SQLException
{
ImmutableList.Builder<String> values = ImmutableList.builder();
for (int index = 0; index < parameters.size(); index++) {
if (!parameters.containsKey(index)) {
throw new SQLException("No value specified for parameter " + (index + 1));
}
values.add(parameters.get(index));
}
return values.build();
}
private void requireNonBatchStatement()View on GitHub (pinned to 55bb57d202)
Solutions
- Use 1-based indexes: the first placeholder (?) in the SQL is parameterIndex 1
- Fix loops to start at 1 and end at parameterCount (inclusive), e.g. for (int i = 1; i <= count; i++)
- If binding from a 0-based collection, use collection.get(i - 1) inside the loop
Example fix
// before
for (int i = 0; i < values.size(); i++) {
ps.setInt(i, values.get(i));
}
// after
for (int i = 0; i < values.size(); i++) {
ps.setInt(i + 1, values.get(i));
} Defensive patterns
Strategy: validation
Validate before calling
void safeSetInt(PreparedStatement ps, int index, int value) throws SQLException {
if (index < 1) throw new IllegalArgumentException("parameterIndex must be >= 1, got " + index);
ps.setInt(index, value);
} Try / catch
// JDBC parameter indexes are 1-based
catch (SQLException e) {
if (e.getMessage().startsWith("Parameter index out of bounds")) {
// fix the off-by-one in setter calls
}
throw e;
} Prevention
- Always treat JDBC parameter indexes as 1-based
- Write binding loops as for (int i = 1; i <= paramCount; i++)
- When mapping from 0-based collections, offset by +1 at the setter call
When it happens
Trigger: Calling ps.setInt(0, x), ps.setNull(-1, Types.INTEGER), etc., or a loop that starts at 0 instead of 1 when binding parameters.
Common situations: Zero-based loop variables carried over from array indexing; dynamic binding built from a 0-based list; off-by-one bugs after adding/removing a parameter.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/0d4d9216f73fb466.
Report an issue: GitHub.