{"record":{"id":"96c8a21909963360","repo":"pentaho/pentaho-kettle","slug":"you-can-not-wait-for-step","errorCode":null,"errorMessage":"You can not wait for step [","messagePattern":"You can not wait for step \\[","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/blockuntilstepsfinish/BlockUntilStepsFinish.java","lineNumber":72,"sourceCode":"\n    if ( first ) {\n      first = false;\n      String[] stepnames = null;\n      int stepnrs = 0;\n      if ( meta.getStepName() != null && meta.getStepName().length > 0 ) {\n        stepnames = meta.getStepName();\n        stepnrs = stepnames.length;\n      } else {\n        throw new KettleException( BaseMessages.getString( PKG, \"BlockUntilStepsFinish.Error.NotSteps\" ) );\n      }\n      // Get target stepnames\n      String[] targetSteps = getTransMeta().getNextStepNames( getStepMeta() );\n\n      data.stepInterfaces = new ConcurrentHashMap<Integer, StepInterface>();\n      for ( int i = 0; i < stepnrs; i++ ) {\n        // We can not get metrics from current step\n        if ( stepnames[i].equals( getStepname() ) ) {\n          throw new KettleException( \"You can not wait for step [\" + stepnames[i] + \"] to finish!\" );\n        }\n        if ( targetSteps != null ) {\n          // We can not metrics from the target steps\n          for ( int j = 0; j < targetSteps.length; j++ ) {\n            if ( stepnames[i].equals( targetSteps[j] ) ) {\n              throw new KettleException( \"You can not get metrics for the target step [\" + targetSteps[j] + \"]!\" );\n            }\n          }\n        }\n\n        int copyNr = Const.toInt( environmentSubstitute( meta.getStepCopyNr()[ i ] ), 0 );\n        StepInterface step = getDispatcher().findBaseSteps( stepnames[i] ).get( copyNr );\n        if ( step == null ) {\n          throw new KettleException( \"Erreur finding step [\" + stepnames[i] + \"] nr copy=\" + copyNr + \"!\" );\n        }\n\n        data.stepInterfaces.put( i, getDispatcher().findBaseSteps( stepnames[i] ).get( copyNr ) );\n      }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/blockuntilstepsfinish/BlockUntilStepsFinish.java#L54-L90","documentation":"The step validates that none of the steps it waits for is itself; a step cannot block on its own completion. If a configured step name equals the current step's name, processRow throws a KettleException 'You can not wait for step [name] to finish!'.","triggerScenarios":"Configuring the BlockUntilStepsFinish step to wait on itself (its own step name entered in the wait list), detected at processRow start by comparing stepnames[i] with getStepname().","commonSituations":"Copy/paste of step configuration across steps without updating the wait list, circular wait definitions built by hand, users misunderstanding that the step must wait on *other* steps.","solutions":["Remove the step's own name from its 'wait for steps' list.","Select only upstream/downstream steps that are not the blocking step itself.","Check for circular wait chains among multiple BlockUntilStepsFinish steps.","Validate the configuration after copy/pasting the step."],"exampleFix":"// before\nwait for steps: [\"Block until steps finish\"]  // itself\n// after\nwait for steps: [\"Sort rows\", \"Stream lookup\"]","handlingStrategy":"validation","validationCode":"// before running: ensure the wait list does not contain the step itself\nBlockUntilStepsFinishMeta m = (BlockUntilStepsFinishMeta) stepMeta.getStepMetaInterface();\nfor (String s : m.getStepName()) {\n  if (s.equals(stepMeta.getName())) {\n    throw new IllegalStateException(\"Step cannot wait for itself: \" + s);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  trans.execute(null);\n} catch (KettleException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"You can not wait for step [\")) {\n    log.error(\"Remove self-reference from wait list: \" + e.getMessage());\n  } else { throw e; }\n}","preventionTips":["After copying step configuration, always update the wait list.","Never list the blocking step's own name in its wait list.","Audit wait lists whenever steps are renamed.","Check for circular wait chains across multiple blocking steps."],"tags":["kettle","configuration","circular-dependency"],"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"}