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
- Fix the row data so every value conforms to its declared ValueMeta type.
- Disable row terminator/trace collection on the step if the snapshot isn't needed.
- Catch KettleStepException, log the offending row, and normalize values before putRow.
- 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
- Match row values to declared value meta types
- Disable row terminator collection in production runs
- Inspect the KettleValueException cause for the failing field
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
- BaseStep.SafeMode.Exception.MixingTypes
- DynamicSQLRow.Exception.TemplateReturnDataTypeError
- ElasticSearchBulk.Error.NoJsonFieldFormat
- Function MOD only works with numeric data
- Function NUM2STR only works on Numbers and Integers
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)