pentaho/pentaho-kettle · error · KettleException
MappingDialog.Exception.OnlyOneMappingOutputStepAllowed
MappingDialog.Exception.OnlyOneMappingOutputStepAllowed
Error message
Without specifying specifif stepnames to write to, there can only be one 'mapping output' step in the mapping and we found {0}. What it means
When no source step name is specified for a mapping output, the sub-transformation must contain exactly one 'Mapping Output' step. If findMappingOutput() finds more than one, the Mapping step cannot choose which one to read from and throws this error with the count found (message contains the typo 'specifif').
Solutions
- Keep exactly one 'Mapping Output' step in the sub-transformation (remove or convert extras).
- Or explicitly pick the source Mapping Output step in the Mapping step dialog's Output tab.
- Route multiple result branches into a single Mapping Output via a 'Stream lookup'/union style step or separate mappings.
- Grep the .ktr for multiple MappingOutput entries to confirm the count.
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
if (Utils.isEmpty(outputDefinition.getInputStepname())) {
long n = mappingTransMeta.getSteps().stream()
.filter(s -> s.getStepMetaInterface() instanceof MappingOutput).count();
if (n != 1) throw new IllegalStateException("Expected 1 Mapping Output step, found " + n);
} Try / catch
try {
mapping.init();
} catch (KettleException e) {
if (String.valueOf(e.getMessage()).contains("only be one 'mapping output'")) {
logError("Multiple Mapping Output steps found — keep one or pick a source explicitly", e);
} else { throw e; }
} Prevention
- Keep exactly one 'Mapping Output' step per mapping sub-transformation.
- Fork outputs upstream or use separate mappings instead of duplicating Mapping Output.
- Audit ktr XML for duplicate MappingOutput entries after merges.
- Specify explicit source step names when multiple outputs are intentional.
When it happens
Trigger: prepareMappingExecution() with empty inputStepname on an output definition and mappingOutputSteps.length > 1 — two or more Mapping Output steps in the sub-transformation and no explicit source selected.
Common situations: Duplicating a Mapping Output step to fork results; merging flows that each had their own Mapping Output; legacy mappings restructured after a refactor.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- MappingDialog.Exception.OneMappingOutputStepRequired
- MappingDialog.Exception.OnlyOneMappingInputStepAllowed
- Mapping.Exception.UnableToInitSingleThreadedTransformation
- Mapping.Exception.UnableToPrepareExecutionOfMapping
- MappingDialog.Exception.OneMappingInputStepRequired
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a99c1d6d2a386bdb.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/mapping/Mapping.java:434
// OK, what is the source (input) step in the mapping: it's the mapping
// output step...
// What step are we reading from here?
//
MappingOutput mappingOutputSource =
(MappingOutput) mappingData.getMappingTrans().findRunThread( outputDefinition.getInputStepname() );
if ( mappingOutputSource == null ) {
// No source step was specified: we're reading from a single Mapping
// Output step.
// We should verify this if this is really the case...
//
MappingOutput[] mappingOutputSteps = mappingData.getMappingTrans().findMappingOutput();
if ( mappingOutputSteps.length == 0 ) {
throw new KettleException( BaseMessages.getString( PKG,
"MappingDialog.Exception.OneMappingOutputStepRequired" ) );
}
if ( mappingOutputSteps.length > 1 ) {
throw new KettleException( BaseMessages.getString( PKG,
"MappingDialog.Exception.OnlyOneMappingOutputStepAllowed", "" + mappingOutputSteps.length ) );
}
mappingOutputSource = mappingOutputSteps[0];
}
// To what steps in this transformation are we writing to?
//
StepInterface[] targetSteps = pickupTargetStepsFor( outputDefinition );
// Now tell the mapping output step where to look...
// Also explain the mapping output steps how to rename the values back...
//
mappingOutputSource
.setConnectorSteps( targetSteps, getData().inputRenameList, outputDefinition.getValueRenames() );
// Is this mapping copying or distributing?
// Make sure the mapping output step mimics this behavior:View on GitHub (pinned to f3058517a1)