pentaho/pentaho-kettle · error · KettleException

TableCompare.Exception.UnexpectedErrorComparingTables

Error message

TableCompare.Exception.UnexpectedErrorComparingTables

What it means

Generic wrapper exception thrown by the public compareTables(RowMetaInterface, Object[]) helper when any Exception occurs while reading the schema/table/key/exclude field values from the input row and delegating to the private compareTables. It wraps the original cause with the message 'Unexpected error comparing tables'.

Solutions

  1. Inspect the chained cause (KettleException.getCause()) to find the underlying error; the wrapper message itself is not actionable.
  2. Verify the reference/compare schema, table, key fields and exclude fields values in the input row are valid and non-null.
  3. Confirm the database connection works and the referenced tables exist and are readable.
  4. If calling the step API directly (as tests do), populate the input row with all required fields in the expected order.

Example fix

// before
Object[] fields = compareTables( getInputRowMeta(), r ); // throws opaque wrapper
// after: guard inputs first
if ( getInputRowMeta().indexOfValue( "compare_table" ) < 0 ) {
  throw new KettleException( "compare_table field missing from input row" );
}
Object[] fields = compareTables( getInputRowMeta(), r );
Defensive patterns

Strategy: try-catch

Validate before calling

// validate all six configured fields resolve in the input row before calling compareTables
for ( String f : new String[] { refSchemaField, refTableField, cmpSchemaField, cmpTableField, keyFieldsField, excludeFieldsField } ) {
  if ( inputRowMeta.indexOfValue( f ) < 0 ) throw new IllegalStateException( "missing field: " + f );
}

Try / catch

try {
  Object[] fields = compareTables( getInputRowMeta(), r );
} catch ( KettleException e ) {
  Throwable root = e;
  while ( root.getCause() != null ) root = root.getCause();
  logError( "Table comparison failed, root cause: " + root.getMessage(), root );
}

Prevention

When it happens

Trigger: Any Exception thrown inside compareTables(rowMeta, r) — e.g. getString() failing on row indices, or the inner private compareTables throwing (SQL errors, missing tables). Called from processRow via the 'fields' local variable assignment at TableCompare.java:183.

Common situations: Database connection failures or bad table/schema names during the actual comparison; NPEs when expected row values are missing; the wrapped cause (getCause()) usually carries the real problem — often surfacing as error 2322 from the deeper overload.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/tablecompare/TableCompare.java:201

    Object[] fields = compareTables( getInputRowMeta(), r );
    Object[] outputRowData = RowDataUtil.addRowData( r, getInputRowMeta().size(), fields );
    putRow( data.outputRowMeta, outputRowData ); // copy row to output rowset(s);
    return true;
  }

  private Object[] compareTables( RowMetaInterface rowMeta, Object[] r ) throws KettleException {
    try {
      String referenceSchema = getInputRowMeta().getString( r, data.refSchemaIndex );
      String referenceTable = getInputRowMeta().getString( r, data.refTableIndex );
      String compareSchema = getInputRowMeta().getString( r, data.cmpSchemaIndex );
      String compareTable = getInputRowMeta().getString( r, data.cmpTableIndex );
      String keyFields = getInputRowMeta().getString( r, data.keyFieldsIndex );
      String excludeFields = getInputRowMeta().getString( r, data.excludeFieldsIndex );

      return compareTables(
        rowMeta, r, referenceSchema, referenceTable, compareSchema, compareTable, keyFields, excludeFields );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString(
        PKG, "TableCompare.Exception.UnexpectedErrorComparingTables" ), e );
    }
  }

  private Object[] compareTables( RowMetaInterface rowMeta, Object[] r, String referenceSchema,
    String referenceTable, String compareSchema, String compareTable, String keyFields, String excludeFields ) throws KettleException {
    long nrErrors = 0L;
    long nrLeftErrors = 0L;
    long nrRightErrors = 0L;
    long nrInnerErrors = 0L;
    long nrRecordsReference = 0L;
    long nrRecordsCompare = 0L;

    Object[] result = new Object[6];

    if ( Utils.isEmpty( referenceTable ) ) {
      Object[] errorRowData = constructErrorRow( rowMeta, r, null, null, null );
      putError( data.errorRowMeta, errorRowData, 1, BaseMessages.getString(

View on GitHub (pinned to f3058517a1)