{"record":{"id":"0d4d9216f73fb466","repo":"prestodb/presto","slug":"parameter-index-out-of-bounds","errorCode":null,"errorMessage":"Parameter index out of bounds: ","messagePattern":"Parameter index out of bounds: ","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoPreparedStatement.java","lineNumber":799,"sourceCode":"    @Override\n    public boolean execute(String sql, String[] columnNames)\n            throws SQLException\n    {\n        throw new SQLException(\"This method cannot be called on PreparedStatement\");\n    }\n\n    @Override\n    public void addBatch(String sql)\n            throws SQLException\n    {\n        throw new SQLException(\"This method cannot be called on PreparedStatement\");\n    }\n\n    private void setParameter(int parameterIndex, String value)\n            throws SQLException\n    {\n        if (parameterIndex < 1) {\n            throw new SQLException(\"Parameter index out of bounds: \" + parameterIndex);\n        }\n        parameters.put(parameterIndex - 1, value);\n    }\n\n    private static List<String> toValues(Map<Integer, String> parameters)\n            throws SQLException\n    {\n        ImmutableList.Builder<String> values = ImmutableList.builder();\n        for (int index = 0; index < parameters.size(); index++) {\n            if (!parameters.containsKey(index)) {\n                throw new SQLException(\"No value specified for parameter \" + (index + 1));\n            }\n            values.add(parameters.get(index));\n        }\n        return values.build();\n    }\n\n    private void requireNonBatchStatement()","sourceCodeStart":781,"sourceCodeEnd":817,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoPreparedStatement.java#L781-L817","documentation":"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.","triggerScenarios":"Calling ps.setInt(0, x), ps.setNull(-1, Types.INTEGER), etc., or a loop that starts at 0 instead of 1 when binding parameters.","commonSituations":"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.","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"],"exampleFix":"// before\nfor (int i = 0; i < values.size(); i++) {\n    ps.setInt(i, values.get(i));\n}\n// after\nfor (int i = 0; i < values.size(); i++) {\n    ps.setInt(i + 1, values.get(i));\n}","handlingStrategy":"validation","validationCode":"void safeSetInt(PreparedStatement ps, int index, int value) throws SQLException {\n    if (index < 1) throw new IllegalArgumentException(\"parameterIndex must be >= 1, got \" + index);\n    ps.setInt(index, value);\n}","typeGuard":null,"tryCatchPattern":"// JDBC parameter indexes are 1-based\ncatch (SQLException e) {\n    if (e.getMessage().startsWith(\"Parameter index out of bounds\")) {\n        // fix the off-by-one in setter calls\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["jdbc","parameter-binding","index-out-of-bounds"],"backgroundTag":"jdbc-parameter-index-out-of-bounds","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}