{"record":{"id":"9e4a84814f9d5488","repo":"pentaho/pentaho-kettle","slug":"multiple-input-or-output-steps-are-not-supported-for-a","errorCode":null,"errorMessage":"Multiple input or output steps are not supported for a single threaded mapping.","messagePattern":"Multiple input or output steps are not supported for a single threaded mapping\\.","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/mapping/Mapping.java","lineNumber":221,"sourceCode":"\n            // Set some statistics from the mapping...\n            // This will show up in Spoon, etc.\n            //\n            Result result = getData().getMappingTrans().getResult();\n            setErrors( result.getNrErrors() );\n            setLinesRead( result.getNrLinesRead() );\n            setLinesWritten( result.getNrLinesWritten() );\n            setLinesInput( result.getNrLinesInput() );\n            setLinesOutput( result.getNrLinesOutput() );\n            setLinesUpdated( result.getNrLinesUpdated() );\n            setLinesRejected( result.getNrLinesRejected() );\n          }\n          return false;\n\n        case SingleThreaded:\n\n          if ( mappingInputs.length > 1 || mappingOutputs.length > 1 ) {\n            throw new KettleException(\n                \"Multiple input or output steps are not supported for a single threaded mapping.\" );\n          }\n\n          // Object[] row = getRow();\n          // RowMetaInterface rowMeta = getInputRowMeta();\n\n          // for (int count=0;count<(data.mappingTransMeta.getSizeRowset()/2) && row!=null;count++) {\n          // // Pass each row over to the mapping input step, fill the buffer...\n          //\n          // mappingInputs[0].getInputRowSets().get(0).putRow(rowMeta, row);\n          //\n          // row = getRow();\n          // }\n\n          if ( ( log != null ) && log.isDebug() ) {\n            List<RowSet> mappingInputRowSets = mappingInputs[0].getInputRowSets();\n            log.logDebug( \"# of input buffers: \" + mappingInputRowSets.size() );\n            if ( mappingInputRowSets.size() > 0 ) {","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/mapping/Mapping.java#L203-L239","documentation":"In Mapping.processRow's SingleThreaded branch, a single-threaded mapping (run in the SingleThreaded execution mode) requires at most one Mapping Input and one Mapping Output step. If mappingInputs.length > 1 or mappingOutputs.length > 1, a KettleException is thrown. Single-threaded execution streams everything through one thread and cannot arbitrate between multiple mapping entry/exit points.","triggerScenarios":"Transformation executed with 'Single Threaded' execution mode (e.g. Trans.TransExecutionMode.SINGLE_THREAD) where the mapped sub-transformation declares more than one Mapping Input step or more than one Mapping Output step — checked in processRow's switch on mappingType == SingleThreaded.","commonSituations":"Reusing an ordinary mapping sub-transf with multiple inputs/outputs inside a single-threaded engine run (used for streaming/low-latency pipelines); switching execution mode to single-threaded without auditing the sub-transf topology.","solutions":["Ensure the sub-transformation has exactly one Mapping Input and one Mapping Output step.","Split the multi-input/multi-output sub-transformation into separate single-threaded mappings.","Run with the standard execution engine instead of Single Threaded if multiple mapping inputs/outputs are required.","Prefer the 'Simple Mapping (sub-transformation)' single-input/single-output style when targeting single-threaded mode."],"exampleFix":"// before\nnew Trans(...).execute(null) with TransExecutionMode.SingleThreaded and sub.ktr having 2 MappingInputs\n// after\n// sub.ktr: keep 1 MappingInput + 1 MappingOutput, or execute with standard engine","handlingStrategy":"validation","validationCode":"// Before enabling Single Threaded execution mode:\nlong in = subTransMeta.getSteps().stream().filter(s -> s.getStepMeta() instanceof MappingInputMeta).count();\nlong out = subTransMeta.getSteps().stream().filter(s -> s.getStepMeta() instanceof MappingOutputMeta).count();\nif (in > 1 || out > 1) throw new IllegalStateException(\"SingleThreaded mapping supports max 1 input and 1 output (got \" + in + \"/\" + out + \")\");","typeGuard":null,"tryCatchPattern":"try {\n  trans.setTransExecutionMode(...); // SingleThreaded\n  trans.execute(null);\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"single threaded mapping\")) {\n    log.error(\"Mapping topology incompatible with SingleThreaded mode: use 1 input/1 output or standard engine\", e);\n  } else { throw e; }\n}","preventionTips":["Design single-threaded mappings with exactly one Mapping Input and one Mapping Output.","Split multi-input/output sub-transformations before single-threaded execution.","Only switch execution modes after auditing mapped sub-transformation topology.","Document execution-mode constraints next to each reusable sub-transformation."],"tags":["mapping","single-threaded","execution-mode","kettle"],"backgroundTag":"unsupported-operation","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"}