pentaho/pentaho-kettle · error · KettleStepException

TableExists.Log.ErrorInStep

Error message

TableExists.Log.ErrorInStep

What it means

TableExists.processRow's catch-all: when a KettleException occurs and the step has NO error handling defined, it logs 'Error in step' and rethrows as KettleStepException, failing the transformation. If error handling IS enabled, the failing row is routed to the error stream instead and this throw does not happen.

Solutions

  1. Read the chained cause (e) in the log to identify the real failure
  2. Right-click the step and define error handling to route bad rows instead of aborting the transformation
  3. Fix the root cause: field mapping or database connectivity

Example fix

// before: step aborts transformation
step -> next
// after: enable error handling
step (right-click) -> Define Error Handling -> target error step
Defensive patterns

Strategy: try-catch

Validate before calling

// enable error handling so bad rows are routed, not fatal
if (!stepMeta.isDoingErrorHandling()) {
  StepErrorMeta em = new StepErrorMeta(transMeta, stepMeta);
  em.setTargetStep(errorStep);
  stepMeta.setErrorMeta(em);
}

Try / catch

try { trans.waitUntilFinished(); if (trans.getErrors() > 0) { inspectStepLog(); } }
catch (KettleStepException e) { logError("TableExists failed: " + e.getCause(), e); }

Prevention

When it happens

Trigger: Any KettleException during step processing (missing field, DB failure) while the step is not connected to an error hop; the original exception is chained as the cause.

Common situations: Transformations run in production without error handling attached; database connectivity failures during the table-existence check; the underlying cause being errors 2332/2333 above.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/tableexists/TableExists.java:108

      // Check if table exists on the specified connection
      tablexists = data.db.checkTableExists( data.realSchemaname, tablename );

      Object[] outputRowData = RowDataUtil.addValueData( r, getInputRowMeta().size(), tablexists );

      // add new values to the row.
      putRow( data.outputRowMeta, outputRowData ); // copy row to output rowset(s);

      if ( log.isRowLevel() ) {
        logRowlevel( BaseMessages.getString( PKG, "TableExists.LineNumber", getLinesRead()
          + " : " + getInputRowMeta().getString( r ) ) );
      }
    } catch ( KettleException e ) {
      if ( getStepMeta().isDoingErrorHandling() ) {
        sendToErrorRow = true;
        errorMessage = e.toString();
      } else {
        logError( BaseMessages.getString( PKG, "TableExists.ErrorInStepRunning" + " : " + e.getMessage() ) );
        throw new KettleStepException( BaseMessages.getString( PKG, "TableExists.Log.ErrorInStep" ), e );
      }
      if ( sendToErrorRow ) {
        // Simply add this row to the error row
        putError( getInputRowMeta(), r, 1, errorMessage, meta.getResultFieldName(), "TableExistsO01" );
      }
    }

    return true;
  }

  public boolean init( StepMetaInterface smi, StepDataInterface sdi ) {
    meta = (TableExistsMeta) smi;
    data = (TableExistsData) sdi;

    if ( super.init( smi, sdi ) ) {
      if ( Utils.isEmpty( meta.getResultFieldName() ) ) {
        logError( BaseMessages.getString( PKG, "TableExists.Error.ResultFieldMissing" ) );
        return false;

View on GitHub (pinned to f3058517a1)