pentaho/pentaho-kettle · error · KettleStepException

Unable to clone row while adding rows to the terminator…

Error message

Unable to clone row while adding rows to the terminator rows.

What it means

When a step has 'row terminator' (trace/preview) collection enabled, putRowError/putRow logic clones the row via rowMeta.cloneRow(row) to store a snapshot in terminator_rows. If cloning throws KettleValueException (a field value can't be converted/copied), it is wrapped in this KettleStepException.

Solutions

  1. Fix the row data so every value conforms to its declared ValueMeta type.
  2. Disable row terminator/trace collection on the step if the snapshot isn't needed.
  3. Catch KettleStepException, log the offending row, and normalize values before putRow.
  4. Check the wrapped KettleValueException cause to find which field fails to clone.

Example fix

// before
row[0] = someRawObject; // not a String, but meta says String
// after
row[0] = valueMeta.getString(someRawObject); // conform to declared type
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure values conform to declared types before putRow
for (int i = 0; i < row.length; i++) {
  row[i] = rowMeta.getValueMeta(i).convertDataCompatible(rowMeta.getValueMeta(i), row[i]);
}

Try / catch

try { putRow(rowMeta, row); }
catch (KettleStepException e) { if (e.getMessage().contains("clone row")) { log.warn("terminator clone failed", e.getCause()); putRowWithoutTrace(rowMeta, row); } else throw e; }

Prevention

When it happens

Trigger: putRow() (or the terminator-rows path) executes while terminator==true and rowMeta.cloneRow(row) fails — usually because a row value doesn't match its declared value meta type (e.g. null handling or an object not convertible to the declared type).

Common situations: Debugging/preview mode with rows containing values inconsistent with declared types; custom steps putting raw Java objects into typed columns while row tracing is on; version differences in ValueMeta clone behavior.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java:1314

          // Ignore
        }
      }
      this.checkTransRunning = true;
    }

    // call all row listeners...
    //
    for ( RowListener listener : rowListeners ) {
      listener.rowWrittenEvent( rowMeta, row );
    }

    // Keep adding to terminator_rows buffer...
    //
    if ( terminator && terminator_rows != null ) {
      try {
        terminator_rows.add( rowMeta.cloneRow( row ) );
      } catch ( KettleValueException e ) {
        throw new KettleStepException( "Unable to clone row while adding rows to the terminator rows.", e );
      }
    }

    outputRowSetsLock.readLock().lock();
    try {
      if ( outputRowSets.isEmpty() ) {
        // No more output rowsets!
        // Still update the nr of lines written.
        //
        incrementLinesWritten();

        return; // we're done here!
      }

      // Repartitioning happens when the current step is not partitioned, but the next one is.
      // That means we need to look up the partitioning information in the next step..
      // If there are multiple steps, we need to look at the first (they should be all the same)
      //

View on GitHub (pinned to f3058517a1)