OpenRefine/OpenRefine · error · IndexOutOfBoundsException
Parameter index out of bounds
Error message
Parameter index out of bounds
What it means
AddRowsCommand.getInsertionIndex parses the 'index' request parameter and validates that it falls within [0, project.rows.size()]. If the parameter is missing, non-numeric, or outside the valid insertion range, the command throws IndexOutOfBoundsException('Parameter index out of bounds').
Solutions
- Pass a valid index between 0 and project.rows.size() (inclusive of size to append at the end)
- Omit or fetch the index fresh from the project right before the call so it reflects current row count
- Use index=0 to insert at the top or index=<rowCount> to append; verify the row count via project data first
- Fix the parameter name — it must be exactly 'index' (INDEX_PARAMETER); a missing parameter makes parseInt throw
Example fix
// before addRows(project, "abc", rows) // non-numeric index // after addRows(project, String.valueOf(project.rows.size()), rows) // append at end
Defensive patterns
Strategy: validation
Validate before calling
if (index === undefined || !Number.isInteger(Number(index)) || Number(index) < 0 || Number(index) > rowCount) throw new Error(`index must be an integer in [0, ${rowCount}]`); Try / catch
try { addRows(project, index, rows); } catch (IndexOutOfBoundsException e) { if (e.getMessage().contains("Parameter index out of bounds")) { index = project.rows.size(); /* append instead */ } else throw e; } Prevention
- Always use 0-based indexes; to append, pass exactly project.rows.size()
- Re-fetch the current row count immediately before each add-rows call
- Ensure the parameter is named 'index' and always present
- Never compute the index from stale snapshots of the project
When it happens
Trigger: POSTing to /command/core/add-rows with an index parameter that is negative, greater than the number of existing rows, absent (NumberFormatException on parseInt of null), or non-numeric text.
Common situations: Automation scripts computing the row index from stale project state after rows were deleted; passing 1-based indexes where 0-based is expected; forgetting the index parameter entirely in API calls.
Related errors
AI-assisted analysis of OpenRefine/OpenRefine@a946177e04 (2026-09-08).
Data as JSON: /api/errors/f159ef367616d776.
Report an issue: GitHub.
Appendix: source
Thrown at main/src/com/google/refine/commands/row/AddRowsCommand.java:80
Project project = getProject(request);
List<Row> rows = getRowData(request);
int insertionIndex = getInsertionIndex(request, project);
AbstractOperation op = new RowAdditionOperation(rows, insertionIndex);
op.validate();
Process process = op.createProcess(project, new Properties());
performProcessAndRespond(request, response, project, process);
} catch (Exception e) {
respondException(response, e);
}
}
public int getInsertionIndex(HttpServletRequest request, Project project) {
String data = request.getParameter(INDEX_PARAMETER);
int index = Integer.parseInt(data);
if (index < 0 || index > project.rows.size()) {
throw new IndexOutOfBoundsException("Parameter " + INDEX_PARAMETER + " out of bounds");
}
return index;
}
public List<Row> getRowData(HttpServletRequest request) throws Exception {
String[] data = request.getParameterValues(ROWS_PARAMETER);
if (data.length == 0) {
throw new IllegalArgumentException("Parameter " + ROWS_PARAMETER + " is empty");
}
List<Row> rows = new ArrayList<>(data.length);
Pool pool = new Pool();
for (String rowStr : data) {
Row row = Row.load(rowStr, pool);
if (!Objects.equals(rowStr, "{}")) {
throw new IllegalArgumentException("Row is not empty");
}
rows.add(row);
}View on GitHub (pinned to a946177e04)