pentaho/pentaho-kettle · error · KettleException

Unsupported situation detected where more than one Mapping…

Error message

Unsupported situation detected where more than one Mapping Output step needs to be handled.  To solve it, insert a dummy step after the mapping step.

What it means

In Mapping.processRow, output row sets can only be attached to mappingOutputs[0].addRowSetToOutputRowSets(...). If the sub-transformation defines more than one Mapping Output step, the destination is ambiguous and a KettleException is thrown. This mirrors the input-side check but for outputs, recommending a dummy step after the mapping.

Solutions

  1. Insert a Dummy step between the Mapping step and the next step in the parent transformation.
  2. Keep exactly one Mapping Output step in the sub-transformation; route multiple streams into it (via union/append) instead.
  3. If multiple outputs are needed, use the 'Mapping (sub-transformation)' with explicit output specification rather than the simple Mapping step.
  4. Audit the sub-transf for duplicate/unused Mapping Output steps and delete them.

Example fix

// before
Mapping(sub.ktr) -----> TextFileOutput   // sub.ktr has MappingOutput1 and MappingOutput2
// after
Mapping(sub.ktr) -----> Dummy -----> TextFileOutput  // or single MappingOutput in sub.ktr
Defensive patterns

Strategy: validation

Validate before calling

// Inspect the sub-transformation before wiring outputs:
long outputs = subTransMeta.getSteps().stream()
  .filter(s -> s.getStepMeta() instanceof MappingOutputMeta).count();
if (outputs > 1) throw new IllegalStateException("Sub-transformation has " + outputs + " Mapping Output steps; add a Dummy after the Mapping or reduce to 1");

Try / catch

try {
  trans.execute(null);
} catch (KettleException e) {
  if (e.getMessage().contains("more than one Mapping Output")) {
    log.error("Ambiguous mapping output wiring: insert a Dummy step after the Mapping step", e);
  } else { throw e; }
}

Prevention

When it happens

Trigger: The Mapping step's sub-transformation contains two or more 'Mapping Output' steps and the parent transformation connects steps after the Mapping, so the resulting output row set cannot be assigned to a single Mapping Output — during output row set wiring in processRow.

Common situations: Sub-transformation built with conditional multi-output paths (multiple Mapping Outputs) reused with a simple Mapping step; leftover extra Mapping Output after refactoring the sub-transf.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

          // Do the same thing for output row sets
          //
          List<RowSet> outputRowSets = getOutputRowSets();
          if ( !outputRowSets.isEmpty() ) {
            for ( RowSet rowSet : outputRowSets ) {
              // Pass this rowset down to a mapping input step in the
              // sub-transformation...
              //
              if ( mappingOutputs.length == 1 ) {
                // Simple case: only one output mapping. Move the RowSet over
                //
                mappingOutputs[0].addRowSetToOutputRowSets( rowSet );
              } else {
                // Difficult to see what's going on here.
                // TODO: figure out where this RowSet needs to go and where it
                // comes from.
                //
                throw new KettleException(
                    "Unsupported situation detected where more than one Mapping Output step needs to be handled.  "
                        + "To solve it, insert a dummy step after the mapping step." );
              }
            }
            clearOutputRowSets();
          }

          // Do the same thing for remote output steps...
          //
          if ( !getRemoteOutputSteps().isEmpty() ) {
            // The remote server is likely a master or a slave server sending data
            // over remotely to this mapping.
            // However, the data needs to end up at a Mapping Output step of the
            // sub-transformation, not in this step.
            // We can move over the remote steps to the Mapping Output step as long
            // as the threads haven't started yet.
            //
            for ( RemoteStep remoteStep : getRemoteOutputSteps() ) {

View on GitHub (pinned to f3058517a1)