pentaho/pentaho-kettle · error · KettleException
SynchronizeAfterMerge.Log.OperationFieldEmpty
SynchronizeAfterMerge.Log.OperationFieldEmpty
Error message
SynchronizeAfterMerge.Log.OperationFieldEmpty
What it means
Thrown in lookupValues() when the 'operation' field value (from the configured OperationOrderField) is null on the incoming row. The SynchronizeAfterMerge step needs a non-null operation marker ('insert', 'update', or 'delete' sentinel values) to decide what SQL to run against the target table. If the field is absent or null on the row, the step cannot classify the row and aborts.
Solutions
- Fix the upstream data so the operation field is never null (e.g. COALESCE(op,'insert') in the SQL or an 'If field value is null' step before this step).
- Verify the 'Operation order field' setting in the step dialog points to the actual field carrying insert/update/delete markers.
- Add a Filter rows step to route rows with a null operation field to an error stream instead of into this step.
- If operation values come from a variable/parameter mapping, check the variable is defined so the field is populated.
Example fix
// before (SQL feeding the step) SELECT id, op FROM staging; // after SELECT id, COALESCE(op, 'insert') AS op FROM staging;
Defensive patterns
Strategy: validation
Validate before calling
// Before the step: reject rows with null operation field
if (getFieldValue(row, "operation") == null) {
throw new ValidationException("operation field is null for row: " + row);
}
// or in SQL: SELECT COALESCE(operation, 'insert') AS operation FROM staging Try / catch
catch (KettleException e) {
if (e.getMessage().contains("OperationFieldEmpty")) {
logError("Operation field is null; fix upstream data or mapping.");
}
throw e;
} Prevention
- Add an 'If field value is null' or COALESCE upstream to default the operation field.
- Filter null-operation rows to an error stream before this step.
- Verify the Operation order field mapping after any upstream schema change.
When it happens
Trigger: processRow calls lookupValues() per input row; operation = row value at the index of meta.getOperationOrderField(). It is null when the input stream's operation field contains a null value, or when the field exists in the dialog config but the upstream step emits null for that row.
Common situations: Upstream table input / lookup returns nulls for the operation column; user configured the wrong operation field name so a wrong (null-typed) column is picked; generated rows omit the operation field for some rows; joins produce null operation values for unmatched records.
Related errors
- Error inserting row into table
- Error updating batch, first 10 errors: Errors encountered…
- GetXMLDataMeta.Exception.ErrorReadingRepository (localized…
- GetXMLDataMeta.Exception.ErrorSavingToRepository (localized…
- StepMeta.Exception.StepCouldNotBeLoaded
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/d262eb24024808a0.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java:78
// do we insert, update or delete ?
String operation = data.inputRowMeta.getString( row, data.indexOfOperationOrderField );
boolean rowIsSafe = false;
boolean sendToErrorRow = false;
String errorMessage = null;
int[] updateCounts = null;
List<Exception> exceptionsList = null;
boolean batchProblem = false;
data.lookupFailure = false;
boolean performInsert = false;
boolean performUpdate = false;
boolean performDelete = false;
boolean lineSkipped = false;
try {
if ( operation == null ) {
throw new KettleException( BaseMessages.getString( PKG, "SynchronizeAfterMerge.Log.OperationFieldEmpty", meta
.getOperationOrderField() ) );
}
if ( meta.istablenameInField() ) {
// get dynamic table name
data.realTableName = data.inputRowMeta.getString( row, data.indexOfTableNameField );
if ( Utils.isEmpty( data.realTableName ) ) {
throw new KettleStepException( "The name of the table is not specified!" );
}
data.realSchemaTable =
data.db.getDatabaseMeta().getQuotedSchemaTableCombination( data.realSchemaName, data.realTableName );
}
if ( operation.equals( data.insertValue ) ) {
// directly insert data into table
/*
*
* INSERT ROWView on GitHub (pinned to f3058517a1)