pentaho/pentaho-kettle · error · KettleException

TableCompare.Exception.KeyFieldsNotSpecified

Error message

TableCompare.Exception.KeyFieldsNotSpecified

What it means

TableCompare requires a 'Key fields' field name to be configured; processRow() validates this with Utils.isEmpty() and throws a KettleException when the setting is blank. This message key (KeyFieldsNotSpecified) signals a missing required configuration value, not a data problem. The step needs the key-fields column to know which fields form the comparison key per row.

Solutions

  1. Open the TableCompare step dialog and enter a value for 'Key fields fieldname'.
  2. If constructing TableCompareMeta in code, call meta.setKeyFieldsField("...") with a field present in the input stream before running.
  3. Validate all required field names (compare table, key fields, exclude fields, key description, value reference, value compare) are set before executing the transformation.

Example fix

// before
TableCompareMeta meta = new TableCompareMeta();
meta.setCompareTableField( "compare_table" ); // key fields field left unset
// after
meta.setKeyFieldsField( "key_fields" );
meta.setDefault(); // fills remaining required settings
Defensive patterns

Strategy: validation

Validate before calling

if ( meta.getKeyFieldsField() == null || meta.getKeyFieldsField().isEmpty() ) {
  throw new IllegalStateException( "TableCompare: Key fields fieldname is required" );
}

Try / catch

try {
  step.processRow();
} catch ( KettleException e ) {
  if ( String.valueOf( e.getLocalizedMessage() ).contains( "KeyFieldsNotSpecified" ) ) {
    logError( "Set 'Key fields fieldname' in the TableCompare dialog and rerun" );
  }
  setErrors( 1 );
  stopAll();
}

Prevention

When it happens

Trigger: meta.getKeyFieldsField() returns empty/null in processRow() — the TableCompare step dialog's 'Key fields fieldname' was never filled in (or was cleared) before the transformation ran.

Common situations: Building the step metadata programmatically (as in test testOutputIsMuchBiggerThanInputDoesntThrowArrayIndexOutOfBounds) and forgetting to set every field; copying an existing step but not re-configuring required fields; a partially filled dialog saved before completion.

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


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

Appendix: source

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

        throw new KettleException( BaseMessages.getString( PKG, "TableCompare.Exception.CanNotFindField", meta
          .getCompareSchemaField() ) );
      }

      // Compare table
      //
      if ( Utils.isEmpty( meta.getCompareTableField() ) ) {
        throw new KettleException( BaseMessages.getString( PKG, "TableCompare.Exception.CompareTableNotSpecified" ) );
      }
      data.cmpTableIndex = getInputRowMeta().indexOfValue( meta.getCompareTableField() );
      if ( data.cmpTableIndex < 0 ) {
        throw new KettleException( BaseMessages.getString( PKG, "TableCompare.Exception.CanNotFindField", meta
          .getCompareTableField() ) );
      }

      // Key fields
      //
      if ( Utils.isEmpty( meta.getKeyFieldsField() ) ) {
        throw new KettleException( BaseMessages.getString( PKG, "TableCompare.Exception.KeyFieldsNotSpecified" ) );
      }
      data.keyFieldsIndex = getInputRowMeta().indexOfValue( meta.getKeyFieldsField() );
      if ( data.keyFieldsIndex < 0 ) {
        throw new KettleException( BaseMessages.getString( PKG, "TableCompare.Exception.CanNotFindField", meta
          .getKeyFieldsField() ) );
      }

      // Exclude fields
      //
      if ( Utils.isEmpty( meta.getExcludeFieldsField() ) ) {
        throw new KettleException( BaseMessages
          .getString( PKG, "TableCompare.Exception.ExcludeFieldsNotSpecified" ) );
      }
      data.excludeFieldsIndex = getInputRowMeta().indexOfValue( meta.getExcludeFieldsField() );
      if ( data.excludeFieldsIndex < 0 ) {
        throw new KettleException( BaseMessages.getString( PKG, "TableCompare.Exception.CanNotFindField", meta
          .getExcludeFieldsField() ) );
      }

View on GitHub (pinned to f3058517a1)