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

  1. Skip the limit/offset positions when binding WHERE parameters; only bind indexes below the WHERE parameter count
  2. Use setLimit(int)/setOffset(int) to change limit/offset values instead of setParameter
  3. 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

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


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)