{"record":{"id":"e676265d4df29c10","repo":"pentaho/pentaho-kettle","slug":"unable-to-clone-row-while-adding-rows-to-the-terminator-rows","errorCode":null,"errorMessage":"Unable to clone row while adding rows to the terminator rows.","messagePattern":"Unable to clone row while adding rows to the terminator rows\\.","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java","lineNumber":1314,"sourceCode":"          // Ignore\n        }\n      }\n      this.checkTransRunning = true;\n    }\n\n    // call all row listeners...\n    //\n    for ( RowListener listener : rowListeners ) {\n      listener.rowWrittenEvent( rowMeta, row );\n    }\n\n    // Keep adding to terminator_rows buffer...\n    //\n    if ( terminator && terminator_rows != null ) {\n      try {\n        terminator_rows.add( rowMeta.cloneRow( row ) );\n      } catch ( KettleValueException e ) {\n        throw new KettleStepException( \"Unable to clone row while adding rows to the terminator rows.\", e );\n      }\n    }\n\n    outputRowSetsLock.readLock().lock();\n    try {\n      if ( outputRowSets.isEmpty() ) {\n        // No more output rowsets!\n        // Still update the nr of lines written.\n        //\n        incrementLinesWritten();\n\n        return; // we're done here!\n      }\n\n      // Repartitioning happens when the current step is not partitioned, but the next one is.\n      // That means we need to look up the partitioning information in the next step..\n      // If there are multiple steps, we need to look at the first (they should be all the same)\n      //","sourceCodeStart":1296,"sourceCodeEnd":1332,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java#L1296-L1332","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nrow[0] = someRawObject; // not a String, but meta says String\n// after\nrow[0] = valueMeta.getString(someRawObject); // conform to declared type","handlingStrategy":"try-catch","validationCode":"// Ensure values conform to declared types before putRow\nfor (int i = 0; i < row.length; i++) {\n  row[i] = rowMeta.getValueMeta(i).convertDataCompatible(rowMeta.getValueMeta(i), row[i]);\n}","typeGuard":null,"tryCatchPattern":"try { putRow(rowMeta, row); }\ncatch (KettleStepException e) { if (e.getMessage().contains(\"clone row\")) { log.warn(\"terminator clone failed\", e.getCause()); putRowWithoutTrace(rowMeta, row); } else throw e; }","preventionTips":["Match row values to declared value meta types","Disable row terminator collection in production runs","Inspect the KettleValueException cause for the failing field"],"tags":["kettle","row-clone","terminator-rows","type-mismatch"],"backgroundTag":"type-mismatch","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"}