{"record":{"id":"3411cdf485fd563a","repo":"pentaho/pentaho-kettle","slug":"basestep-exception-3411cd","errorCode":"BaseStep.Exception.TargetStepToWriteToCantRunInMultipleCopies","errorMessage":"BaseStep.Exception.TargetStepToWriteToCantRunInMultipleCopies","messagePattern":"BaseStep\\.Exception\\.TargetStepToWriteToCantRunInMultipleCopies","errorType":"error_code","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java","lineNumber":2487,"sourceCode":"   * Find output row set.\n   *\n   * @param targetStep the target step\n   * @return the row set\n   * @throws KettleStepException the kettle step exception\n   */\n  public RowSet findOutputRowSet( String targetStep ) throws KettleStepException {\n\n    // Check to see that \"targetStep\" only runs in a single copy\n    // Otherwise you'll see problems during execution.\n    //\n    StepMeta targetStepMeta = transMeta.findStep( targetStep );\n    if ( targetStepMeta == null ) {\n      throw new KettleStepException( BaseMessages.getString(\n        PKG, \"BaseStep.Exception.TargetStepToWriteToDoesntExist\", targetStep ) );\n    }\n\n    if ( targetStepMeta.getCopies() > 1 ) {\n      throw new KettleStepException( BaseMessages.getString(\n        PKG, \"BaseStep.Exception.TargetStepToWriteToCantRunInMultipleCopies\", targetStep, Integer\n          .toString( targetStepMeta.getCopies() ) ) );\n    }\n\n    return findOutputRowSet( getStepname(), getCopy(), targetStep, 0 );\n  }\n\n  /**\n   * Find an output rowset in a running transformation. It will also look at the \"to\" step to see if this is a mapping.\n   * If it is, it will find the appropriate rowset in that transformation.\n   *\n   * @param from\n   * @param fromcopy\n   * @param to\n   * @param tocopy\n   * @return The rowset or null if none is found.\n   */\n  public RowSet findOutputRowSet( String from, int fromcopy, String to, int tocopy ) {","sourceCodeStart":2469,"sourceCodeEnd":2505,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java#L2469-L2505","documentation":"findOutputRowSet(String targetStep) requires the target step to run in a single copy; it throws KettleStepException when targetStepMeta.getCopies() > 1. With multiple copies there are several target row sets, and writing by name alone cannot pick the right one.","triggerScenarios":"Calling findOutputRowSet(targetStep) where the target step is configured with copies N>1 or runs as multiple clustered copies.","commonSituations":"Target step parallelized via 'Change number of copies' to speed up downstream processing; clustered/slave execution duplicating the target; plugin expecting single-copy fan-out semantics.","solutions":["Set the target step's copies to 1, or route through a single dispatcher step before the parallel copies.","Use the copy-aware overload findOutputRowSet(sourceStep, sourceCopy, targetStep, targetCopy) and pick/iterate copies explicitly.","Use partitioning on the target so rows are routed per partition key instead of per copy.","In custom code, write via putRow to all output row sets (getOutputRowSets()) instead of one name-resolved row set."],"exampleFix":"// before\nRowSet rs = findOutputRowSet(\"Parallel Target\"); // 4 copies\n// after\nfor (RowSet rs : getOutputRowSets()) { rs.putRow(rowMeta, row); }","handlingStrategy":"validation","validationCode":"StepMeta tm = transMeta.findStep(targetStepName);\nif (tm != null && tm.getCopies() > 1) throw new IllegalArgumentException(\"Target '\" + targetStepName + \"' runs \" + tm.getCopies() + \" copies; write via getOutputRowSets()\");","typeGuard":null,"tryCatchPattern":"try { RowSet rs = findOutputRowSet(targetStepName); } catch (KettleStepException e) { if (e.getMessage().contains(\"multiple copies\")) { logError(\"Use copy-aware output writing\"); } throw e; }","preventionTips":["Fan out to parallel targets with putRow, not single row set lookup","Keep name-addressable target steps at 1 copy","Prefer partitioning for parallel consumers","Assert single-copy targets in plugin init()"],"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"}