{"record":{"id":"c0cba4fcf66e5cf9","repo":"pentaho/pentaho-kettle","slug":"synchronizeaftermerge-error-samecolumninsertedtwice","errorCode":null,"errorMessage":"SynchronizeAfterMerge.Error.SameColumnInsertedTwice","messagePattern":"SynchronizeAfterMerge\\.Error\\.SameColumnInsertedTwice","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java","lineNumber":739,"sourceCode":"            meta.getKeyStream2()[i] ) );\n        }\n\n        if ( log.isDebug() ) {\n          logDebug( BaseMessages.getString( PKG, \"SynchronizeAfterMerge.Log.FieldHasDataNumbers\", meta\n            .getKeyStream()[i] ) + data.keynrs[i] );\n        }\n      }\n\n      // Insert the update fields: just names. Type doesn't matter!\n      for (int i = 0; i < meta.getUpdateLookup().length; i++) {\n        ValueMetaInterface insValue = data.insertRowMeta.searchValueMeta( meta.getUpdateLookup()[i] );\n        if ( insValue == null ) { // Don't add twice!\n          // we already checked that this value exists so it's probably safe to ignore lookup failure...\n          ValueMetaInterface insertValue = data.inputRowMeta.searchValueMeta( meta.getUpdateStream()[i] ).clone();\n          insertValue.setName( meta.getUpdateLookup()[i] );\n          data.insertRowMeta.addValueMeta( insertValue );\n        } else {\n          throw new KettleStepException( BaseMessages.getString( PKG,\n            \"SynchronizeAfterMerge.Error.SameColumnInsertedTwice\", insValue.getName() ) );\n        }\n      }\n\n      // Cache the position of the compare fields in Row row\n      //\n      data.valuenrs = new int[meta.getUpdateLookup().length];\n      for (int i = 0; i < meta.getUpdateLookup().length; i++) {\n        data.valuenrs[i] = data.inputRowMeta.indexOfValue( meta.getUpdateStream()[i] );\n        if ( data.valuenrs[i] < 0 ) { // couldn't find field!\n          throw new KettleStepException( BaseMessages.getString( PKG, \"SynchronizeAfterMerge.Exception.FieldRequired\",\n            meta.getUpdateStream()[i] ) );\n        }\n        if ( log.isDebug() ) {\n          logDebug( BaseMessages.getString( PKG, \"SynchronizeAfterMerge.Log.FieldHasDataNumbers\", meta\n            .getUpdateStream()[i] ) + data.valuenrs[i] );\n        }\n      }","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java#L721-L757","documentation":"During processRow() the step builds the INSERT row metadata by mapping each Update stream field to an Update lookup (table column). If the target table column (updateLookup[i]) was already added — i.e., the same column appears twice in the Update lookup table — the step throws KettleStepException 'SameColumnInsertedTwice' because a row cannot contain two values for one column.","triggerScenarios":"The 'Update/Insert lookup' grid lists the same table column name in two rows (two stream fields mapped to the same target column), e.g. mapping both amount and old_amount to column amount.","commonSituations":"Copy-pasting rows in the step grid and forgetting to change the lookup column; bulk-loading a mapping where multiple stream fields target one column; merge of step settings from two transformations.","solutions":["Open the Synchronize After Merge dialog and remove or correct duplicate entries in the 'Update lookup' column so each table column appears once","If two stream fields must both be persisted, change one row's lookup column to a distinct table column","Use a stream-to-stream merge (e.g., Stream lookup / Formula) upstream so only one field maps to each column"],"exampleFix":"// before (grid)\nstream: amount    -> lookup: amount\nstream: old_amount-> lookup: amount   // duplicate\n// after\nstream: amount    -> lookup: amount\nstream: old_amount-> lookup: previous_amount  // distinct column","handlingStrategy":"validation","validationCode":"var m = stepMeta.getStepMetaInterface();\nvar seen = {};\nfor (var i = 0; i < m.getUpdateLookup().length; i++) {\n  if (seen[m.getUpdateLookup()[i]]) throw new Error(\"Duplicate lookup column: \" + m.getUpdateLookup()[i]);\n  seen[m.getUpdateLookup()[i]] = true;\n}","typeGuard":null,"tryCatchPattern":"try { trans.execute(...); } catch (KettleException e) { if (e.getMessage().contains(\"SameColumnInsertedTwice\")) { log.error(\"Remove duplicate update-lookup mapping: \" + e.getMessage()); } else throw e; }","preventionTips":["Never copy-paste rows in the mapping grid without editing the lookup column","Enforce one-to-one mapping between stream fields and table columns","Review the mapping grid after merging transformations","Use distinct target columns for distinct stream values"],"tags":["kettle","duplicate-column","step-configuration","etl"],"backgroundTag":"conflicting-config-options","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"}