pentaho/pentaho-kettle · error · RuntimeException
A step in transformation [" + transMeta.toString() + "]…
Error message
A step in transformation [" + transMeta.toString() + "] doesn't have a name. A step should always have a name to identify it by.
What it means
BaseStep's constructor takes the step's name from its StepMeta and throws a RuntimeException if that name is null. Every step must have a name to be identifiable in logging, threading, and the transformation graph. Note it is a RuntimeException, not a KettleException.
Solutions
- Call setName("...") with a unique non-null name on every StepMeta before adding it to the TransMeta.
- If loading from XML, repair the .ktr file so each <step> has a name attribute.
- Validate all step names (non-null, non-blank, unique) before trans.prepareExecution()/execute.
Example fix
// before StepMeta meta = new StepMeta(pluginId, null); // or never named // after StepMeta meta = new StepMeta(pluginId, "Read CSV");
Defensive patterns
Strategy: validation
Validate before calling
for (StepMeta step : transMeta.getSteps()) {
if (step.getName() == null || step.getName().trim().isEmpty())
throw new IllegalStateException("Step without name: " + step);
} Try / catch
try { trans.prepareExecution(); }
catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().contains("doesn't have a name")) { nameAllSteps(transMeta); } else throw e; } Prevention
- Always pass a name in the StepMeta constructor
- Validate step names before prepareExecution
- Never hand-edit .ktr XML name attributes
When it happens
Trigger: Instantiating a step (new SomeStep(StepMeta, StepDataInterface, int, TransMeta, Trans)) when stepMeta.getName() returns null — typically a programmatically built StepMeta that never got setName(), or corrupt .ktr XML where the stepname attribute is missing.
Common situations: Building transformations in code (API-based generation) and forgetting step names; hand-edited or truncated .ktr files; loading metadata where the name attribute was lost.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- AccessInput.Error.ErrorReadingFile
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
- JsonInputException(e)
- Setting a directory on a database connection is not…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/3796277344d89a70.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java:467
* @param stepDataInterface the data object to store temporary data, database connections, caches, result sets,
* hashtables etc.
* @param copyNr The copynumber for this step.
* @param transMeta The TransInfo of which the step stepMeta is part of.
* @param trans The (running) transformation to obtain information shared among the steps.
*/
public BaseStep( StepMeta stepMeta, StepDataInterface stepDataInterface, int copyNr, TransMeta transMeta,
Trans trans ) {
this.stepMeta = stepMeta;
this.stepDataInterface = stepDataInterface;
this.stepcopy = copyNr;
this.transMeta = transMeta;
this.trans = trans;
this.stepname = stepMeta.getName();
this.socketRepository = trans.getSocketRepository();
// Set the name of the thread
if ( stepMeta.getName() == null ) {
throw new RuntimeException( "A step in transformation ["
+ transMeta.toString() + "] doesn't have a name. A step should always have a name to identify it by." );
}
log = KettleLogStore.getLogChannelInterfaceFactory().create( this, trans );
first = true;
clusteredPartitioningFirst = true;
running = new AtomicBoolean( false );
stopped = new AtomicBoolean( false );
safeStopped = new AtomicBoolean( false );
paused = new AtomicBoolean( false );
init = false;
synchronized ( statusCountersLock ) {
linesRead = 0L; // new AtomicLong(0L); // Keep some statistics!
linesWritten = 0L; // new AtomicLong(0L);View on GitHub (pinned to f3058517a1)