{"record":{"id":"75526e927e937462","repo":"pentaho/pentaho-kettle","slug":"multimergejoin-exception-unabletofindfieldinreferencestream","errorCode":"MultiMergeJoin.Exception.UnableToFindFieldInReferenceStream","errorMessage":"MultiMergeJoin.Exception.UnableToFindFieldInReferenceStream","messagePattern":"MultiMergeJoin\\.Exception\\.UnableToFindFieldInReferenceStream","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/multimerge/MultiMergeJoin.java","lineNumber":170,"sourceCode":"      if ( row == null ) {\n        rowMeta = getTransMeta().getStepFields( inputStepName );\n        data.metas[j] = rowMeta;\n      } else {\n        queueEntry.row = row;\n        rowMeta = rowSet.getRowMeta();\n\n        keyField = meta.getKeyFields()[i];\n        String[] keyFieldParts = keyField.split( \",\" );\n        String keyFieldPart;\n        data.keyNrs[j] = new int[keyFieldParts.length];\n        for ( int k = 0; k < keyFieldParts.length; k++ ) {\n          keyFieldPart = keyFieldParts[k];\n          data.keyNrs[j][k] = rowMeta.indexOfValue( keyFieldPart );\n          if ( data.keyNrs[j][k] < 0 ) {\n            String message =\n              BaseMessages.getString( PKG, \"MultiMergeJoin.Exception.UnableToFindFieldInReferenceStream\", keyFieldPart, inputStepName );\n            logError( message );\n            throw new KettleStepException( message );\n          }\n        }\n        data.metas[j] = rowMeta;\n        data.queue.add( data.queueEntries[j] );\n      }\n      data.outputRowMeta.mergeRowMeta( rowMeta.clone() );\n      data.rowLengths[j] = rowMeta.size();\n      data.dummy[j] = RowDataUtil.allocateRowData( rowMeta.size() );\n      j++;\n    }\n    return true;\n  }\n\n  public boolean processRow( StepMetaInterface smi, StepDataInterface sdi ) throws KettleException {\n    meta = (MultiMergeJoinMeta) smi;\n    data = (MultiMergeJoinData) sdi;\n\n    if ( first ) {","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/multimerge/MultiMergeJoin.java#L152-L188","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","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.","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.","Add an upstream step (Select values / Add constants) to create or restore the missing field if it was intentionally removed upstream.","Clear stale metadata by re-editing and re-saving the step so field mappings are revalidated against current row metadata."],"exampleFix":"// before (step XML / metadata: key field not present on second stream)\n<input_step1>streamA</input_step1>\n<key_field1>custId</key_field1>\n<input_step2>streamB</input_step2>\n<key_field2>custID</key_field2>  <!-- typo: field is custId -->\n\n// after\n<key_field2>custId</key_field2>","handlingStrategy":"validation","validationCode":"// Java: before running the join, verify every configured key field exists on each input stream\nfor ( int j = 0; j < inputRowMetas.length; j++ ) {\n  for ( String keyField : keyFieldsPerStream[j] ) {\n    if ( inputRowMetas[j].indexOfValue( keyField ) < 0 ) {\n      throw new IllegalArgumentException(\n        \"Join key field '\" + keyField + \"' missing from input stream \" + j );\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  transformation.execute(...);\n} catch ( KettleStepException e ) {\n  if ( e.getMessage().contains( \"UnableToFindFieldInReferenceStream\" ) ) {\n    // re-check step metadata key fields vs upstream row layouts and fix the mapping\n  } else { throw e; }\n}","preventionTips":["Re-run the step's field refresh after any upstream schema change before saving.","Keep key field lists aligned with input hop order; document which stream each list belongs to.","Use consistent, case-sensitive field naming conventions across upstream steps.","Preview each input stream's output fields before wiring the merge join."],"tags":["kettle","transformation","merge-join","field-lookup","metadata"],"backgroundTag":"invalid-argument-value","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"}