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
- Open the TableCompare step dialog and enter a value for 'Key fields fieldname'.
- If constructing TableCompareMeta in code, call meta.setKeyFieldsField("...") with a field present in the input stream before running.
- 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
- Call meta.setDefault() right after constructing TableCompareMeta programmatically.
- Keep a checklist of the six required field names when building step metadata in code.
- Never save a transformation with required dialog fields blank; validate before execution.
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
- TableCompare.Exception.ExcludeFieldsNotSpecified
- TableCompare.Exception.KeyDescriptionFieldNotSpecified
- TableCompare.Exception.ValueCompareFieldNotSpecified
- TableCompare.Exception.ValueReferenceFieldNotSpecified
- BlockUntilStepsFinish.Error.NotSteps
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)