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

  1. Use 1-based indexes: the first placeholder (?) in the SQL is parameterIndex 1
  2. Fix loops to start at 1 and end at parameterCount (inclusive), e.g. for (int i = 1; i <= count; i++)
  3. 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

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.