{"record":{"id":"04e18e9a0cbb72cb","repo":"pentaho/pentaho-kettle","slug":"basestep-exception","errorCode":"BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies","errorMessage":"BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies","messagePattern":"BaseStep\\.Exception\\.SourceStepToReadFromCantRunInMultipleCopies","errorType":"error_code","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java","lineNumber":2402,"sourceCode":"  /**\n   * Find input row set.\n   *\n   * @param sourceStep the source step\n   * @return the row set\n   * @throws KettleStepException the kettle step exception\n   */\n  public RowSet findInputRowSet( String sourceStep ) throws KettleStepException {\n    // Check to see that \"sourceStep\" only runs in a single copy\n    // Otherwise you'll see problems during execution.\n    //\n    StepMeta sourceStepMeta = transMeta.findStep( sourceStep );\n    if ( sourceStepMeta == null ) {\n      throw new KettleStepException( BaseMessages.getString(\n        PKG, \"BaseStep.Exception.SourceStepToReadFromDoesntExist\", sourceStep ) );\n    }\n\n    if ( sourceStepMeta.getCopies() > 1 ) {\n      throw new KettleStepException( BaseMessages.getString(\n        PKG, \"BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies\", sourceStep, Integer\n          .toString( sourceStepMeta.getCopies() ) ) );\n    }\n\n    return findInputRowSet( sourceStep, 0, getStepname(), getCopy() );\n  }\n\n  /**\n   * Find input row set.\n   *\n   * @param from     the from\n   * @param fromcopy the fromcopy\n   * @param to       the to\n   * @param tocopy   the tocopy\n   * @return the row set\n   */\n  public RowSet findInputRowSet( String from, int fromcopy, String to, int tocopy ) {\n    inputRowSetsLock.readLock().lock();","sourceCodeStart":2384,"sourceCodeEnd":2420,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java#L2384-L2420","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nRowSet rs = findInputRowSet(\"Parallel Source\"); // runs 4 copies\n// after\nfor (RowSet rs : getInputRowSets()) { /* consume all copies */ }","handlingStrategy":"validation","validationCode":"StepMeta sm = transMeta.findStep(sourceStepName);\nif (sm != null && sm.getCopies() > 1) throw new IllegalArgumentException(\"Step '\" + sourceStepName + \"' runs \" + sm.getCopies() + \" copies; use the copy-aware lookup\");","typeGuard":null,"tryCatchPattern":"try { RowSet rs = findInputRowSet(sourceStepName); } catch (KettleStepException e) { if (e.getMessage().contains(\"multiple copies\")) { logError(\"Switch to copy-aware row set access\"); } throw e; }","preventionTips":["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"],"tags":["kettle","pentaho","step-copies","rowset","configuration"],"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"}