pentaho/pentaho-kettle · error · KettleException
SalesforceDelete.Error.DeleteKeyFieldMissing
Error message
SalesforceDelete.Error.DeleteKeyFieldMissing
What it means
SalesforceDelete.processRow validates that the step's delete key field is configured before deleting records from Salesforce. If the 'DeleteField' setting is empty or resolves to an empty string after variable substitution, the step cannot know which input field contains the record IDs to delete, so it aborts with this KettleException.
Solutions
- Open the Salesforce Delete step dialog and set the 'Key field' property to the input field containing the IDs
- Verify the variable used in the field setting is actually defined in the runtime environment (kettle.properties, parameters)
- Re-save the transformation to ensure the DeleteField attribute is persisted
- Add a check in the transformation's initialization (or a Get Variables step) to validate the variable resolves to a non-empty value
Example fix
// before: step meta with empty delete field
meta.setDeleteField("");
// after
meta.setDeleteField("Id"); // or "${SF_DELETE_KEY_FIELD}" with the variable defined in kettle.properties Defensive patterns
Strategy: validation
Validate before calling
// before executing the transformation
String realFieldName = environmentSubstitute(meta.getDeleteField());
if (realFieldName == null || realFieldName.trim().isEmpty()) {
throw new IllegalStateException("Salesforce Delete step: key field (DeleteField) is not set");
} Try / catch
try {
executeTransformation();
} catch (KettleException e) {
if (e.getMessage().contains("DeleteKeyFieldMissing")) {
logError("Configure the Salesforce Delete step's 'Key field' before running");
}
throw e;
} Prevention
- Always set the 'Key field' in the Salesforce Delete step dialog
- Avoid bare ${VARIABLE} references unless the variable is guaranteed defined in kettle.properties or parameters
- Use the step's Check/Verify button to catch missing settings before runtime
- Template transformations with the key field pre-filled
When it happens
Trigger: Running a Salesforce Delete transformation step whose 'Key field' (deleteField) property is blank, or contains only a variable reference that resolves to empty at runtime.
Common situations: A transformation copied or re-created without filling in the key field; environment variable not defined so environmentSubstitute returns empty; step exported/imported without the field persisted.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- ChangeFileEncoding.Error.FilenameFieldMissing
- ChangeFileEncoding.Error.TargetFilenameFieldMissing
- ColumnExists.Error.ColumnnameFieldMissing
- ColumnExists.Error.TablenameFieldMissing
- GetFilesRowsCount.Log.NoField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/3d9aa7ab3a18baeb.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforcedelete/SalesforceDelete.java:75
return false;
}
// If we haven't looked at a row before then do some basic setup.
if ( first ) {
first = false;
data.deleteId = new String[meta.getBatchSizeInt()];
data.outputBuffer = new Object[meta.getBatchSizeInt()][];
// Create the output row meta-data
data.outputRowMeta = getInputRowMeta().clone();
meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
metaStore );
// Check deleteKeyField
String realFieldName = environmentSubstitute( meta.getDeleteField() );
if ( Utils.isEmpty( realFieldName ) ) {
throw new KettleException( BaseMessages.getString( PKG, "SalesforceDelete.Error.DeleteKeyFieldMissing" ) );
}
// return the index of the field in the input stream
data.indexOfKeyField = getInputRowMeta().indexOfValue( realFieldName );
if ( data.indexOfKeyField < 0 ) {
// the field is unreachable!
throw new KettleException( BaseMessages.getString(
PKG, "SalesforceDelete.Error.CanNotFindFDeleteKeyField", realFieldName ) );
}
}
try {
writeToSalesForce( outputRowData );
} catch ( Exception e ) {
throw new KettleStepException( BaseMessages.getString( PKG, "SalesforceDelete.log.Exception" ), e );
}
return true;
}View on GitHub (pinned to f3058517a1)