{"record":{"id":"be10707e67dabf3f","repo":"pentaho/pentaho-kettle","slug":"mappingdialog-exception-onemappingoutputsteprequired","errorCode":"MappingDialog.Exception.OneMappingOutputStepRequired","errorMessage":"You will need to specify a mapping source for this step to function correctly. Please select a valid step name to continue.","messagePattern":"You will need to specify a mapping source for this step to function correctly\\. Please select a valid step name to continue\\.","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/mapping/Mapping.java","lineNumber":430,"sourceCode":"    // However, before we send anything over, let's first explain to the mapping\n    // output steps where the data needs to go...\n    //\n    for ( MappingIODefinition outputDefinition : meta.getOutputMappings() ) {\n      // OK, what is the source (input) step in the mapping: it's the mapping\n      // output step...\n      // What step are we reading from here?\n      //\n      MappingOutput mappingOutputSource =\n          (MappingOutput) mappingData.getMappingTrans().findRunThread( outputDefinition.getInputStepname() );\n      if ( mappingOutputSource == null ) {\n        // No source step was specified: we're reading from a single Mapping\n        // Output step.\n        // We should verify this if this is really the case...\n        //\n        MappingOutput[] mappingOutputSteps = mappingData.getMappingTrans().findMappingOutput();\n\n        if ( mappingOutputSteps.length == 0 ) {\n          throw new KettleException( BaseMessages.getString( PKG,\n              \"MappingDialog.Exception.OneMappingOutputStepRequired\" ) );\n        }\n        if ( mappingOutputSteps.length > 1 ) {\n          throw new KettleException( BaseMessages.getString( PKG,\n              \"MappingDialog.Exception.OnlyOneMappingOutputStepAllowed\", \"\" + mappingOutputSteps.length ) );\n        }\n\n        mappingOutputSource = mappingOutputSteps[0];\n      }\n\n      // To what steps in this transformation are we writing to?\n      //\n      StepInterface[] targetSteps = pickupTargetStepsFor( outputDefinition );\n\n      // Now tell the mapping output step where to look...\n      // Also explain the mapping output steps how to rename the values back...\n      //\n      mappingOutputSource","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/mapping/Mapping.java#L412-L448","documentation":"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.","triggerScenarios":"prepareMappingExecution() handling an output definition with empty inputStepname while the sub-transformation contains no 'Mapping Output' step (mappingOutputSteps.length == 0).","commonSituations":"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.","solutions":["Open the sub-transformation and add a 'Mapping Output' step at the end of the flow.","Verify the Mapping step references the correct sub-transformation that ends with a Mapping Output step.","If the sub-transformation intentionally has multiple outputs, specify the source step name explicitly in the Mapping dialog's output mapping table.","Validate the ktr file is complete after import/export (check XML for MappingOutput step entries)."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"boolean noSource = meta.getOutputMappings().stream()\n    .allMatch(d -> Utils.isEmpty(d.getInputStepname()));\nboolean hasMappingOutput = mappingTransMeta.getSteps().stream()\n    .anyMatch(s -> s.getStepMetaInterface() instanceof MappingOutput);\nif (noSource && !hasMappingOutput) {\n  throw new IllegalStateException(\"Sub-transformation has no 'Mapping Output' step\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  mapping.init();\n} catch (KettleException e) {\n  if (String.valueOf(e.getMessage()).contains(\"'mapping output' step\")\n      || String.valueOf(e.getMessage()).contains(\"mapping source\")) {\n    logError(\"Add a 'Mapping Output' step to the sub-transformation\", e);\n  } else { throw e; }\n}","preventionTips":["Every mapping sub-transformation must end with a 'Mapping Output' step.","Check ktr completeness after imports/exports.","Use the standard mapping template which includes Input/Output steps.","Test the sub-transformation as a mapping in dev before promotion."],"tags":["pdi","kettle","mapping-step","mapping-output","missing-step"],"backgroundTag":"missing-required-config-field","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"}