pentaho/pentaho-kettle · error · KettleException

MultiMergeJoin.Log.UnableToFindReferenceStream

MultiMergeJoin.Log.UnableToFindReferenceStream

Error message

MultiMergeJoin.Log.UnableToFindReferenceStream

What it means

MultiMergeJoin.processFirstRow() iterates its info streams and resolves each input step's metadata. If a stream's StepMeta is null (the configured input step name cannot be resolved to an actual step in the transformation), a KettleException 'UnableToFindReferenceStream' is thrown. The in-code comment notes init() should normally have caught this.

Solutions

  1. Open the MultiMergeJoin step dialog, verify every listed input step exists and is connected, then re-save
  2. Fix the transformation XML: correct or remove the stale step reference and re-add the hop
  3. Recreate the hop in Spoon by dragging from the actual input step to the join
  4. Validate the TransMeta programmatically before running (transMeta.checkSteps() / verify all hop sources resolve)

Example fix

// before (stale reference in generated metadata)
joinMeta.getMainStepName(); // references "inputA" which was renamed to "inputA2"
// after
transMeta.findStep( "inputA2" ); // update join config to the real step name, reconnect hop, then run
Defensive patterns

Strategy: validation

Validate before calling

for ( String name : joinMeta.getInputStepNames() ) {
  if ( transMeta.findStep( name ) == null ) {
    throw new IllegalStateException( "MultiMergeJoin references non-existent input step: " + name );
  }
}
transMeta.checkSteps(); // also surfaces dangling references

Type guard

function allInputsResolve( transMeta, joinMeta ) {
  return joinMeta.getInfoStreams().every( s => s.getStepMeta() != null );
}

Try / catch

try {
  trans.execute( null );
  trans.waitUntilFinished();
} catch ( KettleException e ) {
  if ( e.getMessage() != null && e.getMessage().contains( "UnableToFindReferenceStream" ) ) {
    // fix stale step reference / reconnect hop in transformation metadata
  } else { throw e; }
}

Prevention

When it happens

Trigger: Running a transformation where a MultiMergeJoin input stream's source step name is set but the step does not exist in the transformation graph (e.g. step deleted/renamed after the join was configured), so stream.getStepMeta() returns null.

Common situations: Hand-edited or programmatically generated ktr XML referencing a nonexistent step name; renaming an input step without reconnecting the hop; XML import where hop definitions were lost.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/multimerge/MultiMergeJoin.java:88

    TransHopMeta transHopMeta;

    StepIOMetaInterface stepIOMeta = meta.getStepIOMeta();
    List<StreamInterface> infoStreams = stepIOMeta.getInfoStreams();
    StreamInterface stream;
    StepMeta toStepMeta = meta.getParentStepMeta();
    StepMeta fromStepMeta;

    ArrayList<String> inputStepNameList = new ArrayList<String>();
    String[] inputStepNames = meta.getInputSteps();
    String inputStepName;

    for ( int i = 0; i < infoStreams.size(); i++ ) {
      inputStepName = inputStepNames[i];
      stream = infoStreams.get( i );
      fromStepMeta = stream.getStepMeta();
      if ( fromStepMeta == null ) {
        //should not arrive here, shoud typically have been caught by init.
        throw new KettleException(
          BaseMessages.getString( PKG, "MultiMergeJoin.Log.UnableToFindReferenceStream", inputStepName ) );
      }
      //check the hop
      transHopMeta = transMeta.findTransHop( fromStepMeta,  toStepMeta, true );
      //there is no hop: this is unexpected.
      if ( transHopMeta == null ) {
        //should not arrive here, shoud typically have been caught by init.
        throw new KettleException(
          BaseMessages.getString( PKG, "MultiMergeJoin.Log.UnableToFindReferenceStream", inputStepName ) );
      } else if ( transHopMeta.isEnabled() ) {
        inputStepNameList.add( inputStepName );
      } else {
        logDetailed( BaseMessages.getString( PKG, "MultiMergeJoin.Log.IgnoringStep", inputStepName ) );
      }
    }

    int streamSize = inputStepNameList.size();
    if ( streamSize == 0 ) {

View on GitHub (pinned to f3058517a1)