pentaho/pentaho-kettle · error · RuntimeException
Unable to pass the new row to the next step(s) because of…
Error message
Unable to pass the new row to the next step(s) because of an error:
What it means
Thrown by the putRow added function in ScriptAddedFunctions, which forwards a row to the next transform step(s). After obtaining the step binding and calling putRow(outputRowMeta, newRow), any exception is wrapped in a RuntimeException with this message.
Solutions
- Read the wrapped cause after the message (e.toString()) to identify the underlying failure (NPE, cast, metadata mismatch).
- Ensure putRow is called during row processing, after the step has initialized output row metadata.
- Make sure the emitted Object[] matches the output row layout (correct number/order of fields), typically produced via createRowCopy.
- If the script should end processing rather than forward a row, use the appropriate abort/stop mechanism instead of putRow.
Example fix
// before putRow(someString); // wrong type/layout // after var newRow = createRowCopy(2); newRow[1] = someString; putRow(newRow);
Defensive patterns
Strategy: try-catch
Validate before calling
if (typeof row === 'undefined' || row === null) throw new Error('no row to output');
if (typeof putRow !== 'function') throw new Error('putRow not available in this step'); Type guard
function isObjectArray(x) { return x != null && Object.prototype.toString.call(x) === '[object Array]'; } Try / catch
try {
putRow(newRow);
} catch (e) {
if (String(e).indexOf('Unable to pass the new row') !== -1) {
// verify output metadata exists and newRow matches output layout
} else { throw e; }
} Prevention
- Emit rows that match the configured output fields (use createRowCopy)
- Call putRow only during row processing, not before step init
- Read the wrapped cause to distinguish metadata vs data problems
- Avoid putRow in script variants where the step cannot forward rows
When it happens
Trigger: Calling putRow(newRow) in a script when (a) the bound step object's putRow or getOutputRowMeta throws (no output metadata yet, transform not started properly), (b) newRow is not a valid Object[] matching the output row metadata, or (c) the ScriptDummy fallback putRow fails.
Common situations: Emitting rows before output row metadata is established, passing a row array whose length/field layout doesn't match the configured output fields, or calling putRow from a script step variant where the step binding doesn't support row output.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The function call createRowCopy requires a single arguments…
- The function call getInputRowMeta doesn't require arguments.
- Unable to create a row copy:
- Unable to get the input row metadata because of an error:
- Calculator.ErrorInStepRunning
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/408c4b284ebd2f66.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptAddedFunctions.java:1939
// put a row out to the next steps...
//
public static void putRow( ScriptEngine actualContext, Bindings actualObject, Object[] ArgList,
Object FunctionContext ) {
if ( ArgList.length == 1 ) {
try {
Object[] newRow = (Object[]) ArgList[0];
Object scmO = actualObject.get( "_step_" );
try {
Script step = (Script) scmO;
step.putRow( step.getOutputRowMeta(), newRow );
} catch ( Exception e ) {
ScriptDummy step = (ScriptDummy) scmO;
step.putRow( step.getOutputRowMeta(), newRow );
}
} catch ( Exception e ) {
throw new RuntimeException( "Unable to pass the new row to the next step(s) because of an error: "
+ Const.CR + e.toString() );
}
} else {
throw new RuntimeException( "The function call putRow requires 1 argument : the output row data (Object[])" );
}
}
public static void deleteFile( Bowl bowl, ScriptEngine actualContext, Bindings actualObject, Object[] ArgList,
Object FunctionContext ) {
try {
if ( ArgList.length == 1 && !isNull( ArgList[0] ) && !isUndefined( ArgList[0] ) ) {
// Object act = actualObject.get("_step_", actualObject);
// ScriptValuesMod act = (ScriptValuesMod)Context.toType(scm_delete, ScriptValuesMod.class);
FileObject fileObject = null;
try {View on GitHub (pinned to f3058517a1)