pentaho/pentaho-kettle · error · KettleStepException

MultiMergeJoin.Exception.UnableToFindFieldInReferenceStream

MultiMergeJoin.Exception.UnableToFindFieldInReferenceStream

Error message

MultiMergeJoin.Exception.UnableToFindFieldInReferenceStream

What it means

Thrown by MultiMergeJoin.processFirstRow when a join key field configured for an input stream cannot be found in that stream's row metadata: rowMeta.indexOfValue(keyFieldPart) returns -1. The step merges multiple sorted input streams on key fields, and every key field named in the step metadata must exist in the corresponding input stream's row layout. The message names both the missing field and the input step whose stream lacks it.

Solutions

  1. Open the MultiMerge Join step dialog and verify each key field name exactly matches a field of the corresponding input stream (case-sensitive); fix or re-select the field.
  2. Run the transformation and inspect the upstream step's output fields (right-click > Show output fields) to confirm the key field exists at runtime on that stream.
  3. Check that key fields are assigned to the correct input stream: the step stores keyNrs per stream index j, so field list order must match input hop order.
  4. Add an upstream step (Select values / Add constants) to create or restore the missing field if it was intentionally removed upstream.
  5. Clear stale metadata by re-editing and re-saving the step so field mappings are revalidated against current row metadata.

Example fix

// before (step XML / metadata: key field not present on second stream)
<input_step1>streamA</input_step1>
<key_field1>custId</key_field1>
<input_step2>streamB</input_step2>
<key_field2>custID</key_field2>  <!-- typo: field is custId -->

// after
<key_field2>custId</key_field2>
Defensive patterns

Strategy: validation

Validate before calling

// Java: before running the join, verify every configured key field exists on each input stream
for ( int j = 0; j < inputRowMetas.length; j++ ) {
  for ( String keyField : keyFieldsPerStream[j] ) {
    if ( inputRowMetas[j].indexOfValue( keyField ) < 0 ) {
      throw new IllegalArgumentException(
        "Join key field '" + keyField + "' missing from input stream " + j );
    }
  }
}

Try / catch

try {
  transformation.execute(...);
} catch ( KettleStepException e ) {
  if ( e.getMessage().contains( "UnableToFindFieldInReferenceStream" ) ) {
    // re-check step metadata key fields vs upstream row layouts and fix the mapping
  } else { throw e; }
}

Prevention

When it happens

Trigger: processFirstRow (called from processRow) iterates the key fields of each input stream and calls indexOfValue on the incoming RowMeta; it throws KettleStepException whenever any configured key field is absent from the referenced input step's fields, typically on the first row of execution.

Common situations: A join key was renamed or typo'd in the MultiMerge Join step dialog; an upstream step was changed so the field no longer exists or is removed before the join; the key field was configured for the wrong input stream (streams are matched positionally to key field lists); transformations edited after upstream metadata changed without re-running the step's field refresh.

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/75526e927e937462. Report an issue: GitHub.

Appendix: source

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

      if ( row == null ) {
        rowMeta = getTransMeta().getStepFields( inputStepName );
        data.metas[j] = rowMeta;
      } else {
        queueEntry.row = row;
        rowMeta = rowSet.getRowMeta();

        keyField = meta.getKeyFields()[i];
        String[] keyFieldParts = keyField.split( "," );
        String keyFieldPart;
        data.keyNrs[j] = new int[keyFieldParts.length];
        for ( int k = 0; k < keyFieldParts.length; k++ ) {
          keyFieldPart = keyFieldParts[k];
          data.keyNrs[j][k] = rowMeta.indexOfValue( keyFieldPart );
          if ( data.keyNrs[j][k] < 0 ) {
            String message =
              BaseMessages.getString( PKG, "MultiMergeJoin.Exception.UnableToFindFieldInReferenceStream", keyFieldPart, inputStepName );
            logError( message );
            throw new KettleStepException( message );
          }
        }
        data.metas[j] = rowMeta;
        data.queue.add( data.queueEntries[j] );
      }
      data.outputRowMeta.mergeRowMeta( rowMeta.clone() );
      data.rowLengths[j] = rowMeta.size();
      data.dummy[j] = RowDataUtil.allocateRowData( rowMeta.size() );
      j++;
    }
    return true;
  }

  public boolean processRow( StepMetaInterface smi, StepDataInterface sdi ) throws KettleException {
    meta = (MultiMergeJoinMeta) smi;
    data = (MultiMergeJoinData) sdi;

    if ( first ) {

View on GitHub (pinned to f3058517a1)