pentaho/pentaho-kettle · error · KettleStepException

ColumnExists.Log.ErrorInStep

Error message

ColumnExists.Log.ErrorInStep

What it means

Catch-all handler in processRow: when a KettleException occurs and the transformation does NOT define error handling for this step, the step logs 'Error in step' and rethrows as KettleStepException, killing the transformation. If error handling IS enabled, the row is routed to the error stream instead.

Solutions

  1. Attach an error handling hop to the step to route bad rows to an error stream instead of aborting
  2. Fix the root cause reported in the wrapped exception's cause and log message
  3. Check the Kettle log for the preceding 'ColumnExists...' message identifying the actual failure
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the step has error handling defined before running programmatically
if (!stepMeta.isDoingErrorHandling()) {
  stepMeta.setSupportsErrorHandling(true); // attach an error hop in the TransMeta
}

Try / catch

try {
  trans.execute(null);
  trans.waitUntilFinished();
} catch (KettleException e) {
  Throwable root = e; while (root.getCause() != null) root = root.getCause();
  log.error("ColumnExists step failed: " + root.getMessage(), root);
}

Prevention

When it happens

Trigger: Any of the earlier KettleExceptions (missing tablename field, field not found in row, database errors from checkColumnExists) propagates to the catch block while getStepMeta().isDoingErrorHandling() is false.

Common situations: Running a transformation whose ColumnExists step failed field lookup or DB access without an error hop attached; users confused why the underlying message is wrapped.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/columnexists/ColumnExists.java:146

      // Check if table exists on the specified connection
      columnexists = data.db.checkColumnExists( columnname, data.tablename );

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

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

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

    return true;
  }

  public boolean init( StepMetaInterface smi, StepDataInterface sdi ) {
    meta = (ColumnExistsMeta) smi;
    data = (ColumnExistsData) sdi;

    if ( super.init( smi, sdi ) ) {
      if ( !meta.isTablenameInField() ) {
        if ( Utils.isEmpty( meta.getTablename() ) ) {
          logError( BaseMessages.getString( PKG, "ColumnExists.Error.TablenameMissing" ) );

View on GitHub (pinned to f3058517a1)