pentaho/pentaho-kettle · error · KettleStepException
BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies
BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies
Error message
BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies
What it means
findInputRowSet(String sourceStep) requires the source step to run in a single copy; after confirming it exists, it throws KettleStepException when sourceStepMeta.getCopies() > 1. With multiple copies there are several row sets from that step, so a single name-based lookup is ambiguous.
Solutions
- Set the source step's copies to 1 in its dialog (right-click > Change number of copies).
- Use the multi-copy-aware overload findInputRowSet(sourceStep, sourceStepCopy, targetStep, targetCopy) and iterate over copies explicitly.
- Partition the source step instead of running copies, so a single logical copy is addressable.
- In custom code, enumerate row sets via getInputRowSets() rather than resolving one by name.
Example fix
// before
RowSet rs = findInputRowSet("Parallel Source"); // runs 4 copies
// after
for (RowSet rs : getInputRowSets()) { /* consume all copies */ } Defensive patterns
Strategy: validation
Validate before calling
StepMeta sm = transMeta.findStep(sourceStepName);
if (sm != null && sm.getCopies() > 1) throw new IllegalArgumentException("Step '" + sourceStepName + "' runs " + sm.getCopies() + " copies; use the copy-aware lookup"); Try / catch
try { RowSet rs = findInputRowSet(sourceStepName); } catch (KettleStepException e) { if (e.getMessage().contains("multiple copies")) { logError("Switch to copy-aware row set access"); } throw e; } Prevention
- Keep name-resolvable source steps at 1 copy
- Document copy-count requirements of custom steps
- Prefer partitioning over copies when row set addressing is needed
- Check getCopies() in plugin init before runtime lookup
When it happens
Trigger: Calling findInputRowSet(sourceStep) where the referenced step has 'Copies' set to N>1 or is launched in multiple copies via clustering/variable-driven copy count.
Common situations: User set 'Execute for each row' / copies to parallelize the source; clustered transformation where the source runs on several slaves; a plugin expecting single-copy semantics used against a partitioned source.
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
- BaseStep.Exception.TargetStepToWriteToCantRunInMultipleCopies
- BaseStep.Exception.SourceStepToReadFromDoesntExist
- BaseStep.Exception.TargetStepToWriteToDoesntExist
- A deadlock was detected between steps
- AddSequence.Exception.NoSpecifiedMethod
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/04e18e9a0cbb72cb.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java:2402
/**
* Find input row set.
*
* @param sourceStep the source step
* @return the row set
* @throws KettleStepException the kettle step exception
*/
public RowSet findInputRowSet( String sourceStep ) throws KettleStepException {
// Check to see that "sourceStep" only runs in a single copy
// Otherwise you'll see problems during execution.
//
StepMeta sourceStepMeta = transMeta.findStep( sourceStep );
if ( sourceStepMeta == null ) {
throw new KettleStepException( BaseMessages.getString(
PKG, "BaseStep.Exception.SourceStepToReadFromDoesntExist", sourceStep ) );
}
if ( sourceStepMeta.getCopies() > 1 ) {
throw new KettleStepException( BaseMessages.getString(
PKG, "BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies", sourceStep, Integer
.toString( sourceStepMeta.getCopies() ) ) );
}
return findInputRowSet( sourceStep, 0, getStepname(), getCopy() );
}
/**
* Find input row set.
*
* @param from the from
* @param fromcopy the fromcopy
* @param to the to
* @param tocopy the tocopy
* @return the row set
*/
public RowSet findInputRowSet( String from, int fromcopy, String to, int tocopy ) {
inputRowSetsLock.readLock().lock();View on GitHub (pinned to f3058517a1)