pentaho/pentaho-kettle · error · KettleException

Unable to find thread with name

Error message

Unable to find thread with name ${stepname} and copy number ${copynr}

What it means

Trans.addRowProducer(stepname, copynr) injects rows into an already-prepared transformation step, but first looks up the step's thread. If no running step thread matches the given name and copy number, it throws this KettleException.

Solutions

  1. Ensure prepareExecution() (or execute()) was called before addRowProducer
  2. Verify the step name exactly matches the step's name in the transformation (case-sensitive) and the copynr is within its cop ies count
  3. Print available steps: iterate transMeta.getSteps() to confirm the name/copy you pass
  4. For transformations loaded from a repository, use the step name as stored, not a renamed label

Example fix

// before
trans.prepareExecution(new String[0]);
RowProducer rp = trans.addRowProducer("Inpu t", 0); // typo
// after
RowProducer rp = trans.addRowProducer("Input", 0);
Defensive patterns

Strategy: validation

Validate before calling

// verify the step exists before calling addRowProducer
boolean found = transMeta.getSteps().stream()
  .anyMatch(sm -> sm.getName().equals(stepName) && sm.getCopies(transMeta) > copyNr);
if (!found) throw new IllegalArgumentException("No such step: " + stepName + "#" + copyNr);
// and ensure threads exist
trans.prepareExecution(new String[0]);

Try / catch

try {
  RowProducer rp = trans.addRowProducer(stepName, copyNr);
} catch (KettleException e) {
  if (e.getMessage().startsWith("Unable to find thread")) {
    throw new IllegalArgumentException("Step/copy not running: " + stepName + "/" + copyNr, e);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling addRowProducer with a step name that doesn't exist in the transformation, a wrong copynr for a multi-copy step, or calling it before prepareExecution()/execute() so threads aren't registered yet.

Common situations: Typo in step name (names are case-sensitive), forgetting that clustered/split transformations run per-slave copies, invoking addRowProducer on a transformation not yet prepared.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/5353f156f608112a. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/Trans.java:3457

  public boolean isSafeModeEnabled() {
    return safeModeEnabled;
  }

  /**
   * This adds a row producer to the transformation that just got set up. It is preferable to run this BEFORE execute()
   * but after prepareExecution()
   *
   * @param stepname The step to produce rows for
   * @param copynr   The copynr of the step to produce row for (normally 0 unless you have multiple copies running)
   * @return the row producer
   * @throws KettleException in case the thread/step to produce rows for could not be found.
   * @see Trans#execute(String[])
   * @see Trans#prepareExecution(String[])
   */
  public RowProducer addRowProducer( String stepname, int copynr ) throws KettleException {
    StepInterface stepInterface = getStepInterface( stepname, copynr );
    if ( stepInterface == null ) {
      throw new KettleException( "Unable to find thread with name " + stepname + " and copy number " + copynr );
    }

    // We are going to add an extra RowSet to this stepInterface.
    RowSet rowSet;
    switch ( transMeta.getTransformationType() ) {
      case Normal:
        rowSet = new BlockingRowSet( transMeta.getSizeRowset() );
        break;
      case SerialSingleThreaded:
        rowSet = new SingleRowRowSet();
        break;
      case SingleThreaded:
        rowSet = new QueueRowSet();
        break;
      default:
        throw new KettleException( "Unhandled transformation type: " + transMeta.getTransformationType() );
    }

View on GitHub (pinned to f3058517a1)