pentaho/pentaho-kettle · error · KettleException

SalesforceUpsertDialog.FieldsMissing.DialogMessage

Error message

SalesforceUpsertDialog.FieldsMissing.DialogMessage

What it means

Thrown in SalesforceUpsert.processRow when the step's update field mapping grid is empty — meta.getUpdateLookup().length is 0. An upsert step with nothing to update is treated as a configuration error and aborts the transformation rather than silently doing nothing.

Solutions

  1. Open the Salesforce Upsert step dialog and populate the 'Update fields' table (field to update + stream field).
  2. Verify the saved ktr contains the <updateLookup>/<updateStream> grid entries.
  3. Re-enter external-ID and field mappings if a version upgrade dropped the grid contents.

Example fix

// before (transformation XML)
<fields/>
// after
<fields>
  <field>
    <lookup>Name</lookup>
    <stream>name</stream>
  </field>
</fields>
Defensive patterns

Strategy: validation

Validate before calling

if (meta.getUpdateLookup() == null || meta.getUpdateLookup().length == 0) {
  throw new KettleException("Salesforce Upsert step has no update field mappings configured");
}

Try / catch

try { return processRow(row); } catch (KettleException e) { if (e.getMessage().contains("FieldsMissing")) { log.error("Configure the update field grid in the step dialog"); } throw e; }

Prevention

When it happens

Trigger: Running a Salesforce Upsert step whose 'Update fields' table has zero rows: the user never opened/configured the step, or the grid was cleared after editing the ktr XML.

Common situations: Transformation copied from a template where the upsert mapping was never filled in; settings lost after XML/repository edit; grid accidentally emptied in the dialog and saved.

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


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

Appendix: source

Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforceupsert/SalesforceUpsert.java:89

        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, "SalesforceUpsertDialog.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( BaseMessages.getString( PKG, "SalesforceUpsert.FieldNotFound", meta
            .getUpdateStream()[i] ) );
        }
      }

View on GitHub (pinned to f3058517a1)