pentaho/pentaho-kettle · error · KettleException

MappingDialog.Exception.OneMappingOutputStepRequired

MappingDialog.Exception.OneMappingOutputStepRequired

Error message

You will need to specify a mapping source for this step to function correctly. Please select a valid step name to continue.

What it means

When no explicit source step name is given for a mapping output definition, the sub-transformation must contain exactly one 'Mapping Output' step. If findMappingOutput() returns zero steps, the mapping has no place to hand rows back to the parent, so this exception is thrown.

Solutions

  1. Open the sub-transformation and add a 'Mapping Output' step at the end of the flow.
  2. Verify the Mapping step references the correct sub-transformation that ends with a Mapping Output step.
  3. If the sub-transformation intentionally has multiple outputs, specify the source step name explicitly in the Mapping dialog's output mapping table.
  4. Validate the ktr file is complete after import/export (check XML for MappingOutput step entries).

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

boolean noSource = meta.getOutputMappings().stream()
    .allMatch(d -> Utils.isEmpty(d.getInputStepname()));
boolean hasMappingOutput = mappingTransMeta.getSteps().stream()
    .anyMatch(s -> s.getStepMetaInterface() instanceof MappingOutput);
if (noSource && !hasMappingOutput) {
  throw new IllegalStateException("Sub-transformation has no 'Mapping Output' step");
}

Try / catch

try {
  mapping.init();
} catch (KettleException e) {
  if (String.valueOf(e.getMessage()).contains("'mapping output' step")
      || String.valueOf(e.getMessage()).contains("mapping source")) {
    logError("Add a 'Mapping Output' step to the sub-transformation", e);
  } else { throw e; }
}

Prevention

When it happens

Trigger: prepareMappingExecution() handling an output definition with empty inputStepname while the sub-transformation contains no 'Mapping Output' step (mappingOutputSteps.length == 0).

Common situations: Sub-transformation built without a Mapping Output step; standalone transformation reused as a mapping; transformation truncated during copy/import so the Mapping Output step was lost.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/be10707e67dabf3f. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/mapping/Mapping.java:430

    // However, before we send anything over, let's first explain to the mapping
    // output steps where the data needs to go...
    //
    for ( MappingIODefinition outputDefinition : meta.getOutputMappings() ) {
      // 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

View on GitHub (pinned to f3058517a1)