{"record":{"id":"d262eb24024808a0","repo":"pentaho/pentaho-kettle","slug":"synchronizeaftermerge-log-operationfieldempty","errorCode":"SynchronizeAfterMerge.Log.OperationFieldEmpty","errorMessage":"SynchronizeAfterMerge.Log.OperationFieldEmpty","messagePattern":"SynchronizeAfterMerge\\.Log\\.OperationFieldEmpty","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java","lineNumber":78,"sourceCode":"    // do we insert, update or delete ?\n    String operation = data.inputRowMeta.getString( row, data.indexOfOperationOrderField );\n\n    boolean rowIsSafe = false;\n    boolean sendToErrorRow = false;\n    String errorMessage = null;\n    int[] updateCounts = null;\n    List<Exception> exceptionsList = null;\n    boolean batchProblem = false;\n\n    data.lookupFailure = false;\n    boolean performInsert = false;\n    boolean performUpdate = false;\n    boolean performDelete = false;\n    boolean lineSkipped = false;\n\n    try {\n      if ( operation == null ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"SynchronizeAfterMerge.Log.OperationFieldEmpty\", meta\n          .getOperationOrderField() ) );\n      }\n\n      if ( meta.istablenameInField() ) {\n        // get dynamic table name\n        data.realTableName = data.inputRowMeta.getString( row, data.indexOfTableNameField );\n        if ( Utils.isEmpty( data.realTableName ) ) {\n          throw new KettleStepException( \"The name of the table is not specified!\" );\n        }\n        data.realSchemaTable =\n          data.db.getDatabaseMeta().getQuotedSchemaTableCombination( data.realSchemaName, data.realTableName );\n      }\n\n      if ( operation.equals( data.insertValue ) ) {\n        // directly insert data into table\n        /*\n         *\n         * INSERT ROW","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java#L60-L96","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (SQL feeding the step)\nSELECT id, op FROM staging;\n// after\nSELECT id, COALESCE(op, 'insert') AS op FROM staging;","handlingStrategy":"validation","validationCode":"// Before the step: reject rows with null operation field\nif (getFieldValue(row, \"operation\") == null) {\n  throw new ValidationException(\"operation field is null for row: \" + row);\n}\n// or in SQL: SELECT COALESCE(operation, 'insert') AS operation FROM staging","typeGuard":null,"tryCatchPattern":"catch (KettleException e) {\n  if (e.getMessage().contains(\"OperationFieldEmpty\")) {\n    logError(\"Operation field is null; fix upstream data or mapping.\");\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["database","missing-field-value","pentaho-kettle"],"backgroundTag":"null-argument","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}