greenrobot/greenDAO · error · IllegalArgumentException
Illegal parameter index:
Error message
Illegal parameter index:
What it means
Query objects built with QueryBuilder.limit()/offset() reserve special parameter positions for LIMIT/OFFSET. setParameter(index) throws IllegalArgumentException when the given index targets the reserved limit or offset position, since those slots hold SQL limit/offset values, not WHERE parameters.
Solutions
- Skip the limit/offset positions when binding WHERE parameters; only bind indexes below the WHERE parameter count
- Use setLimit(int)/setOffset(int) to change limit/offset values instead of setParameter
- Check AbstractQueryWithLimit's limitPosition/offsetPosition (or count only WHERE parameters) before binding
Example fix
// before
for (int i = 0; i < parameters.length; i++) { query.setParameter(i, values[i]); } // may hit limit position
// after
for (int i = 0; i < whereParameterCount; i++) { query.setParameter(i, values[i]); }
query.setLimit(20); Defensive patterns
Strategy: validation
Validate before calling
if (index == limitPosition || index == offsetPosition) {
throw new IllegalArgumentException("index " + index + " is reserved for LIMIT/OFFSET");
} Try / catch
try {
query.setParameter(index, value);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Illegal parameter index")) {
// adjust index mapping to exclude limit/offset slots
}
} Prevention
- Track the WHERE-parameter count separately from limit/offset positions
- Use setLimit/setOffset instead of setParameter for those values
- Don't iterate over raw parameter arrays including reserved slots
When it happens
Trigger: Calling query.setParameter(limitPosition, ...) or setParameter(offsetPosition, ...), e.g. assuming indexes cover all parameters including limit/offset added via QueryBuilder.limit()/offset().
Common situations: Iterating over a parameter count that includes limit/offset slots; reusing a generic parameter-binding helper against a query built with limit/offset.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Table alias required
- Limit must be set with QueryBuilder before it can be used…
- Offset must be set with QueryBuilder before it can be used…
- Expected unique result, but count was
- Duplicate property ordinals
AI-assisted analysis of greenrobot/greenDAO@0bbb338e17 (2026-09-08).
Data as JSON: /api/errors/b14ad70e542958be.
Report an issue: GitHub.
Appendix: source
Thrown at DaoCore/src/main/java/org/greenrobot/greendao/query/AbstractQueryWithLimit.java:44
// TODO Query for PKs/ROW IDs
abstract class AbstractQueryWithLimit<T> extends AbstractQuery<T> {
protected final int limitPosition;
protected final int offsetPosition;
protected AbstractQueryWithLimit(AbstractDao<T, ?> dao, String sql, String[] initialValues, int limitPosition,
int offsetPosition) {
super(dao, sql, initialValues);
this.limitPosition = limitPosition;
this.offsetPosition = offsetPosition;
}
/**
* Sets the parameter (0 based) using the position in which it was added during building the query. Note: all
* standard WHERE parameters come first. After that come the WHERE parameters of joins (if any).
*/
public AbstractQueryWithLimit<T> setParameter(int index, Object parameter) {
if (index >= 0 && (index == limitPosition || index == offsetPosition)) {
throw new IllegalArgumentException("Illegal parameter index: " + index);
}
return (AbstractQueryWithLimit<T>) super.setParameter(index, parameter);
}
/**
* Sets the limit of the maximum number of results returned by this Query. {@link
* org.greenrobot.greendao.query.QueryBuilder#limit(int)} must
* have been called on the QueryBuilder that created this Query object.
*/
public void setLimit(int limit) {
checkThread();
if (limitPosition == -1) {
throw new IllegalStateException("Limit must be set with QueryBuilder before it can be used here");
}
parameters[limitPosition] = Integer.toString(limit);
}
/**View on GitHub (pinned to 0bbb338e17)