pentaho/pentaho-kettle · error · KettleException
MergeJoin.Exception.UnableToFindSpecifiedStep
MergeJoin.Exception.UnableToFindSpecifiedStep
Error message
MergeJoin.Exception.UnableToFindSpecifiedStep
What it means
MergeJoin.processRow() locates the RowSet for its first (reference) input stream by step name via findInputRowSet(). When it returns null — no such input rowset is registered for this step — it throws this KettleException naming the missing step. The merge join cannot read sorted input from its first hop, so processing aborts.
Solutions
- Open the Merge Join step dialog and verify both input steps listed exist and are connected with hops.
- Re-create the hop from the first (reference) source step to the Merge Join step after any rename.
- Ensure both source steps are enabled and part of the executed transformation.
- If building the transformation in code, call meta.getStepIOMeta().getInfoStreams() updates and set correct step names before execution.
Example fix
// before: stale step name after rename
infoStreams.get(0).setStepname("Old Source");
// after: reference the actual connected step
infoStreams.get(0).setStepname("Sorted Customer Rows"); // step that actually hops into Merge Join Defensive patterns
Strategy: validation
Validate before calling
// before execution, verify both inputs are connected
for (StreamInterface stream : mergeJoinMeta.getStepIOMeta().getInfoStreams()) {
StepMeta source = transMeta.findStep(stream.getStepname());
if (source == null || !transMeta.isStepUsedInHops(source)) {
throw new IllegalStateException("MergeJoin input step missing/disconnected: " + stream.getStepname());
}
} Type guard
boolean hasConnectedInput(TransMeta transMeta, StreamInterface stream) {
StepMeta s = transMeta.findStep(stream.getStepname());
return s != null && !s.isDisabled() && transMeta.isStepUsedInHops(s);
} Try / catch
try {
processRow();
} catch (KettleException e) {
if (e.getMessage().contains("UnableToFindSpecifiedStep")) {
logError("Reconnect the missing MergeJoin input hop in Spoon and re-run", e);
}
throw e;
} Prevention
- After renaming any input step, reopen the Merge Join dialog and reselect it.
- Run Spoon's hop/step verification before executing transformations.
- Avoid copying Merge Join steps between transformations without rewiring.
- Don't disable source steps that feed a merge join.
When it happens
Trigger: The step listed first in the MergeJoin meta's info streams has no connected hop into the Merge Join step — hop deleted or renamed, step name mismatch, or the transformation was executed with a disabled/removed source step.
Common situations: Renaming the first input step without re-opening the Merge Join dialog (hop references stale names); copying a Merge Join step into another transformation without reconnecting inputs; disabling a source step during debugging; partial transformations assembled programmatically.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- A deadlock was detected between steps
- BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies
- BaseStep.Exception.TargetStepToWriteToCantRunInMultipleCopies
- BaseStep.Exception.SourceStepToReadFromDoesntExist
- BaseStep.Exception.TargetStepToWriteToDoesntExist
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/b1aea08c6c3f31ae.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/mergejoin/MergeJoin.java:76
Trans trans ) {
super( stepMeta, stepDataInterface, copyNr, transMeta, trans );
}
public boolean processRow( StepMetaInterface smi, StepDataInterface sdi ) throws KettleException {
meta = (MergeJoinMeta) smi;
data = (MergeJoinData) sdi;
int compare;
if ( first ) {
first = false;
// Find the RowSet to read from
//
List<StreamInterface> infoStreams = meta.getStepIOMeta().getInfoStreams();
data.oneRowSet = findInputRowSet( infoStreams.get( 0 ).getStepname() );
if ( data.oneRowSet == null ) {
throw new KettleException( BaseMessages.getString(
PKG, "MergeJoin.Exception.UnableToFindSpecifiedStep", infoStreams.get( 0 ).getStepname() ) );
}
data.twoRowSet = findInputRowSet( infoStreams.get( 1 ).getStepname() );
if ( data.twoRowSet == null ) {
throw new KettleException( BaseMessages.getString(
PKG, "MergeJoin.Exception.UnableToFindSpecifiedStep", infoStreams.get( 1 ).getStepname() ) );
}
data.one = getRowFrom( data.oneRowSet );
if ( data.one != null ) {
data.oneMeta = data.oneRowSet.getRowMeta();
} else {
data.one = null;
data.oneMeta = getTransMeta().getStepFields( infoStreams.get( 0 ).getStepname() );
}
data.two = getRowFrom( data.twoRowSet );View on GitHub (pinned to f3058517a1)