pentaho/pentaho-kettle · error · KettleException
You can not wait for step [
Error message
You can not wait for step [
What it means
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!'.
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.
Example fix
// before wait for steps: ["Block until steps finish"] // itself // after wait for steps: ["Sort rows", "Stream lookup"]
Defensive patterns
Strategy: validation
Validate before calling
// before running: ensure the wait list does not contain the step itself
BlockUntilStepsFinishMeta m = (BlockUntilStepsFinishMeta) stepMeta.getStepMetaInterface();
for (String s : m.getStepName()) {
if (s.equals(stepMeta.getName())) {
throw new IllegalStateException("Step cannot wait for itself: " + s);
}
} Try / catch
try {
trans.execute(null);
} catch (KettleException e) {
if (e.getMessage() != null && e.getMessage().startsWith("You can not wait for step [")) {
log.error("Remove self-reference from wait list: " + e.getMessage());
} else { throw e; }
} Prevention
- 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.
When it happens
Trigger: 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().
Common situations: 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.
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
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
- AddSequence.Exception.NoSpecifiedMethod
- At this time we don't support the use of multiple cluster…
- AutoDoc.Exception.FilenameFieldNotFound
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/96c8a21909963360.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/blockuntilstepsfinish/BlockUntilStepsFinish.java:72
if ( first ) {
first = false;
String[] stepnames = null;
int stepnrs = 0;
if ( meta.getStepName() != null && meta.getStepName().length > 0 ) {
stepnames = meta.getStepName();
stepnrs = stepnames.length;
} else {
throw new KettleException( BaseMessages.getString( PKG, "BlockUntilStepsFinish.Error.NotSteps" ) );
}
// Get target stepnames
String[] targetSteps = getTransMeta().getNextStepNames( getStepMeta() );
data.stepInterfaces = new ConcurrentHashMap<Integer, StepInterface>();
for ( int i = 0; i < stepnrs; i++ ) {
// We can not get metrics from current step
if ( stepnames[i].equals( getStepname() ) ) {
throw new KettleException( "You can not wait for step [" + stepnames[i] + "] to finish!" );
}
if ( targetSteps != null ) {
// We can not metrics from the target steps
for ( int j = 0; j < targetSteps.length; j++ ) {
if ( stepnames[i].equals( targetSteps[j] ) ) {
throw new KettleException( "You can not get metrics for the target step [" + targetSteps[j] + "]!" );
}
}
}
int copyNr = Const.toInt( environmentSubstitute( meta.getStepCopyNr()[ i ] ), 0 );
StepInterface step = getDispatcher().findBaseSteps( stepnames[i] ).get( copyNr );
if ( step == null ) {
throw new KettleException( "Erreur finding step [" + stepnames[i] + "] nr copy=" + copyNr + "!" );
}
data.stepInterfaces.put( i, getDispatcher().findBaseSteps( stepnames[i] ).get( copyNr ) );
}View on GitHub (pinned to f3058517a1)