OpenRefine/OpenRefine · error · java.lang.IllegalArgumentException
Column '" + columnName + "' is referenced in the list of…
Error message
Column '" + columnName + "' is referenced in the list of operations but is absent from the project
What it means
ApplyOperationsCommand.doPost() validates an uploaded operations recipe against the project schema before applying it. If recipe.getRequiredColumns() names a column that does not exist in project.columnModel, it throws IllegalArgumentException so the whole batch is rejected rather than failing mid-application.
Solutions
- Open the recipe JSON and remove or fix operations referencing the missing column
- Rename/rename the target column in the project to match the recipe, or adjust the recipe's column names
- Regenerate the recipe from a project with the same schema
- Check requiredColumns in the response error to see exactly which column is missing
Example fix
// before: recipe references column 'country' but project has 'Country'
{"op":"core/column-addition","columnName":"country",...}
// after: fix name to match project schema
{"op":"core/column-addition","columnName":"Country",...} Defensive patterns
Strategy: try-catch
Validate before calling
// before POST
recipe.requiredColumns.forEach(c => { if (!projectColumns.includes(c)) throw new Error('missing column: ' + c); }); Try / catch
try { applyOperations(recipe); } catch (IllegalArgumentException e) { if (e.getMessage().contains("absent from the project")) { reconcileSchema(recipe, project); } } Prevention
- Only reuse recipes between projects with identical schemas
- Check requiredColumns against the target project first
- Re-record recipes after column renames
When it happens
Trigger: POSTing a JSON operations list to /command/core/apply-operations where an operation (e.g. a column edit or key-value columnize) references a column absent from the current project — often because the recipe came from a different project or the column was renamed/deleted.
Common situations: Reusing exported operation JSON across projects; applying recipes to a dataset with different headers; column renames upstream of the recipe; recording on one file and replaying on another.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Column ' ' already exists in the project
- Arrays and objects aren't comparable
- Bad number found in date
- Bad string " " in
- Bad time " " in date
AI-assisted analysis of OpenRefine/OpenRefine@a946177e04 (2026-09-08).
Data as JSON: /api/errors/88a0ca3768df787c.
Report an issue: GitHub.
Appendix: source
Thrown at main/src/com/google/refine/commands/history/ApplyOperationsCommand.java:117
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
Recipe recipe = ParsingUtilities.mapper.readValue(jsonString, Recipe.class);
recipe.validate();
if (!renames.isEmpty()) {
recipe = recipe.renameColumns(renames);
}
// deduplicate internal column names to make sure they don't conflict with the ones in the project
if (!recipe.getInternalColumns().isEmpty()) {
recipe = recipe.avoidInternalColumnCollisions(project.columnModel.getColumnNames().stream().collect(Collectors.toSet()));
}
// check all required columns are present
Set<String> requiredColumns = recipe.getRequiredColumns();
for (String columnName : requiredColumns) {
if (project.columnModel.getColumnByName(columnName) == null) {
throw new IllegalArgumentException(
"Column '" + columnName + "' is referenced in the list of operations but is absent from the project");
}
}
// check all new columns are not present
Set<String> newColumns = recipe.getNewColumns();
for (String columnName : newColumns) {
if (project.columnModel.getColumnByName(columnName) != null) {
throw new IllegalArgumentException(
"Column '" + columnName + "' already exists in the project");
}
}
// Run all operations in sequence
List<HistoryEntry> entries = new ArrayList<>(recipe.getOperations().size());
for (AbstractOperation operation : recipe.getOperations()) {
Process process = operation.createProcess(project, new Properties());
HistoryEntry entry = project.processManager.queueProcess(process);View on GitHub (pinned to a946177e04)