pentaho/pentaho-kettle · error · KettleStepException

The same column can't be inserted into the target row…

Error message

The same column can't be inserted into the target row twice: 

What it means

The step builds the INSERT row by renaming each Update Stream value to its Update Lookup (target table column) name. If two update field entries map to the same target column, prepareInsert would fail, so the step pre-empts it by rejecting duplicate insert columns. Message is hardcoded English (not i18n).

Solutions

  1. Open the 'Update fields' grid and remove or re-map the duplicate entry so each Update Lookup (table column) is unique.
  2. Use the Enter field mapping wizard to rebuild a correct one-to-one mapping.
  3. If editing step XML or repository attributes directly, deduplicate the value_name entries.
  4. Save and re-run; the check compares insert value names during row metadata construction.

Example fix

// before (two entries both map to column "qty")
fields[0].setUpdateLookup("qty"); fields[1].setUpdateLookup("qty");
// after
fields[0].setUpdateLookup("qty_in"); fields[1].setUpdateLookup("qty_out");
Defensive patterns

Strategy: validation

Validate before calling

java.util.Set<String> seen = new java.util.HashSet<>();
for (InsertUpdateField uf : meta.getUpdateFields()) {
  if (!seen.add(uf.getUpdateLookup()))
    throw new IllegalStateException("Duplicate target column in update fields: " + uf.getUpdateLookup());
}

Type guard

boolean noDuplicateLookups(java.util.List<InsertUpdateField> fields) {
  long distinct = fields.stream().map(InsertUpdateField::getUpdateLookup).distinct().count();
  return distinct == fields.size();
}

Try / catch

try { trans.execute(...); } catch (KettleStepException e) {
  if (e.getMessage().startsWith("The same column can't be inserted")) { /* dedupe update-fields grid */ }
  throw e;
}

Prevention

When it happens

Trigger: Two entries in the 'Update fields' grid have the same Update Lookup (table column) value, e.g. the same table column listed twice or mapped from two streams.

Common situations: Copy-pasted row in the update fields grid with the table field left unchanged; duplicate column mapping introduced by hand-edited step XML; mapping generated twice appending duplicates.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/1085ea8af341a36f. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/insertupdate/InsertUpdate.java:273

      setLookup( getInputRowMeta() );

      data.insertRowMeta = new RowMeta();

      // Insert the update fields: just names. Type doesn't matter!
      for ( int i = 0; i < meta.getUpdateFields().length; i++ ) {
        ValueMetaInterface insValue =
          data.insertRowMeta.searchValueMeta( meta.getUpdateFields()[ i ].getUpdateLookup() );
        if ( insValue == null ) {
          // Don't add twice!

          // we already checked that this value exists so it's probably safe to ignore lookup failure...
          ValueMetaInterface insertValue =
            getInputRowMeta().searchValueMeta( meta.getUpdateFields()[ i ].getUpdateStream() ).clone();
          insertValue.setName( meta.getUpdateFields()[ i ].getUpdateLookup() );
          data.insertRowMeta.addValueMeta( insertValue );
        } else {
          throw new KettleStepException( "The same column can't be inserted into the target row twice: "
            + insValue.getName() ); // TODO i18n
        }
      }
      data.db.prepareInsert(
        data.insertRowMeta, environmentSubstitute( meta.getSchemaName() ), environmentSubstitute( meta
          .getTableName() ) );

      if ( !meta.isUpdateBypassed() ) {
        List<String> updateColumns = new ArrayList<String>();
        for ( int i = 0; i < meta.getUpdateFields().length; i++ ) {
          if ( meta.getUpdateFields()[ i ].getUpdate().booleanValue() ) {
            updateColumns.add( meta.getUpdateFields()[ i ].getUpdateLookup() );
          }
        }
        prepareUpdate( getInputRowMeta() );
      }
    }

View on GitHub (pinned to f3058517a1)