pentaho/pentaho-kettle · error · KettleException
The simple mapping step needs one Mapping Output step to…
Error message
The simple mapping step needs one Mapping Output step to read from in the sub-transformation
What it means
The Simple Mapping step executes a sub-transformation and pipes rows through a Mapping Input step into the sub-transformation and out through a Mapping Output step. During prepareMappingExecution, findMappingOutput() scans the sub-transformation for Mapping Output steps; if none exist there is no step to read resulting rows from, so a KettleException is thrown.
Solutions
- Open the sub-transformation referenced by the Simple Mapping step and add a Mapping Output step, connecting it to the rest of the sub-transformation's stream.
- Verify the mapping transformation reference (file name / repository directory + entry) points at the intended mapping, not a different transformation.
- If multiple Mapping Output steps exist by mistake, remove all but one (SimpleMapping supports exactly one).
- Ensure the sub-transformation is saved and re-loaded after edits so findMappingOutput() sees the current step set.
Example fix
// Sub-transformation wrong: rows go to a normal 'Table output' step with no mapping output // Fix: add a 'Mapping output' step and wire the sub-transformation stream into it // ... -> Mapping output // then in the parent transformation's Simple Mapping step, keep the reference to that sub-transformation
Defensive patterns
Strategy: validation
Validate before calling
// Before running, verify the mapping sub-transformation has exactly one Mapping Output step
TransMeta mappingTransMeta = new TransMeta(mappingFilePath);
MappingOutput[] outputs = new MappingTransMeta(mappingTransMeta, null).findMappingOutput();
if (outputs == null || outputs.length == 0) {
throw new IllegalStateException("Mapping sub-transformation '" + mappingFilePath + "' has no Mapping Output step");
} Try / catch
try {
step.init(beforeExecutionData); // SimpleMapping init
} catch (KettleException e) {
logError("Sub-transformation is missing its Mapping Output step: " + e.getMessage());
return false; // fail fast with a clear configuration message
} Prevention
- Always create mapping sub-transformations from the Mapping template so a Mapping Output step exists by default
- Review sub-transformations in CI: assert exactly one Mapping Input and one Mapping Output step per mapping
- Never delete the Mapping Output step when editing a mapping's downstream logic
When it happens
Trigger: SimpleMapping.prepareMappingExecution() (invoked from step init()) calls simpleMappingData.mappingTrans.findMappingOutput() and gets a zero-length array because the referenced sub-transformation contains no Mapping Output step.
Common situations: Developer points the Simple Mapping step at a sub-transformation that was built without a Mapping Output step (e.g. a normal transformation reused as a mapping, or the sub-transformation was edited and the Mapping Output step deleted), or the wrong transformation file/repository entry is referenced so the loaded sub-trans is not the intended mapping.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- The simple mapping step does not support multiple Mapping…
- Mapping.Exception.UnableToPrepareExecutionOfMapping
- MappingInput.Exception.UnableToConnectWithParentMapping
- No mapping (sub-transformation) was specified or it was not…
- Unable to load the mapping transformation
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/784321d3a7cc1d91.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/simplemapping/SimpleMapping.java:197
if ( mappingInputs.length == 0 ) {
throw new KettleException(
"The simple mapping step needs one Mapping Input step to write to in the sub-transformation" );
}
if ( mappingInputs.length > 1 ) {
throw new KettleException(
"The simple mapping step does not support multiple Mapping Input steps to write to in the sub-transformation" );
}
simpleMappingData.mappingInput = mappingInputs[0];
simpleMappingData.mappingInput.setConnectorSteps( new StepInterface[0], new ArrayList<MappingValueRename>(), null );
// LogTableField readField = data.mappingTransMeta.getTransLogTable().findField(TransLogTable.ID.LINES_READ);
// if (readField.getSubject() == null) {
// readField.setSubject(data.mappingInput.getStepMeta());
// }
MappingOutput[] mappingOutputs = simpleMappingData.mappingTrans.findMappingOutput();
if ( mappingOutputs.length == 0 ) {
throw new KettleException(
"The simple mapping step needs one Mapping Output step to read from in the sub-transformation" );
}
if ( mappingOutputs.length > 1 ) {
throw new KettleException( "The simple mapping step does not support "
+ "multiple Mapping Output steps to read from in the sub-transformation" );
}
simpleMappingData.mappingOutput = mappingOutputs[0];
// LogTableField writeField = data.mappingTransMeta.getTransLogTable().findField(TransLogTable.ID.LINES_WRITTEN);
// if (writeField.getSubject() == null && data.mappingOutputs != null && data.mappingOutputs.length >= 1) {
// writeField.setSubject(data.mappingOutputs[0].getStepMeta());
// }
// Finally, add the mapping transformation to the active sub-transformations
// map in the parent transformation
//
getTrans().addActiveSubTransformation( getStepname(), simpleMappingData.mappingTrans );
}View on GitHub (pinned to f3058517a1)