pentaho/pentaho-kettle · error · KettleException
SalesforceUpdateDialog.FieldsMissing.DialogMessage
Error message
SalesforceUpdateDialog.FieldsMissing.DialogMessage
What it means
In SalesforceUpdate.processRow(), if the update mapping grid contains zero fields (meta.getUpdateLookup().length == 0), the step throws a KettleException with message key 'SalesforceUpdateDialog.FieldsMissing.DialogMessage'. The step refuses to run because there is nothing to update in Salesforce — the field mapping between the stream and Salesforce fields was never configured.
Solutions
- Open the Salesforce Update step dialog and populate the lookup/update field grid before running.
- Verify the .ktr XML for the step contains the expected update_lookup/update_stream entries.
- If building metadata in code, call allocate(n) plus setUpdateLookup/setUpdateStream with n > 0.
Example fix
// before: step metadata with empty mapping
meta.setUpdateLookup(new String[0]);
meta.setUpdateStream(new String[0]);
// after
meta.allocate(1);
meta.setUpdateLookup(new String[] { "Id" });
meta.setUpdateStream(new String[] { "account_id" }); Defensive patterns
Strategy: validation
Validate before calling
// Validate mapping before executing the transformation
SalesforceUpdateMeta meta = (SalesforceUpdateMeta) stepMeta.getStepMetaInterface();
if (meta.getUpdateLookup() == null || meta.getUpdateLookup().length == 0) {
throw new IllegalArgumentException(
"Salesforce Update step '" + stepMeta.getName() + "' has no field mapping configured");
} Try / catch
try {
trans.execute(null);
} catch (KettleException e) {
if (e.getMessage().contains("FieldsMissing")) {
log.error("Configure the Salesforce Update field mapping before running");
}
throw e;
} Prevention
- Always open and configure new Salesforce steps before running the transformation.
- Validate metadata programmatically (meta.check()) before scheduling runs.
- When generating steps in code, call allocate(n) with n > 0 and set both lookup and stream arrays.
- Diff .ktr files after edits to confirm the mapping grid entries persisted.
When it happens
Trigger: Executing a transformation whose Salesforce Update step has an empty 'Update lookup fields' table — e.g. the step was dropped and run without configuring the mapping, or the grid was cleared.
Common situations: New step added but never configured; mapping lost after loading metadata from an incompatible source; generated transformations programmatically without calling setUpdateLookup/setUpdateStream.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
- Field [ ] couldn't be found in the input stream!
- Group field ' ' could not be found in the input stream
- SalesforceInsert.CanNotFindField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/5fd23fa0f4b69fe0.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforceupdate/SalesforceUpdate.java:79
flushBuffers();
}
setOutputDone();
return false;
}
// If we haven't looked at a row before then do some basic setup.
if ( first ) {
first = false;
data.sfBuffer = new SObject[meta.getBatchSizeInt()];
data.outputBuffer = new Object[meta.getBatchSizeInt()][];
// get total fields in the grid
data.nrfields = meta.getUpdateLookup().length;
// Check if field list is filled
if ( data.nrfields == 0 ) {
throw new KettleException( BaseMessages.getString( PKG,
"SalesforceUpdateDialog.FieldsMissing.DialogMessage" ) );
}
// Create the output row meta-data
data.inputRowMeta = getInputRowMeta().clone();
data.outputRowMeta = data.inputRowMeta.clone();
meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
metaStore );
// Build the mapping of input position to field name
data.fieldnrs = new int[meta.getUpdateStream().length];
for ( int i = 0; i < meta.getUpdateStream().length; i++ ) {
data.fieldnrs[i] = getInputRowMeta().indexOfValue( meta.getUpdateStream()[i] );
if ( data.fieldnrs[i] < 0 ) {
throw new KettleException( "Field [" + meta.getUpdateStream()[i]
+ "] couldn't be found in the input stream!" );
}
}View on GitHub (pinned to f3058517a1)