pentaho/pentaho-kettle · error · KettleException

SalesforceUpsert.FieldNotFound

Error message

SalesforceUpsert.FieldNotFound

What it means

Thrown in SalesforceUpsert.processRow when one of the fields named in the step's update mapping does not exist in the incoming row's row-meta (indexOfValue returns < 0). The step builds a fieldname→index map and aborts rather than silently skipping a mapped field.

Solutions

  1. Read the message's field name and add/restore that field on the stream feeding the upsert step.
  2. Open the Salesforce Upsert dialog and update the mapping to an existing incoming field name.
  3. Check upstream steps (Select Values, filter, renamed CSV headers) that may have removed or renamed the column.
  4. Ensure field name casing matches exactly — Kettle field lookups are case-sensitive.

Example fix

// before: upstream renamed field
"oldName" -> Select Values rename -> "customerName" // upsert still maps "oldName"
// after: update the upsert mapping
<stream>customerName</stream>  // was <stream>oldName</stream>
Defensive patterns

Strategy: validation

Validate before calling

for (String fieldName : meta.getUpdateStream()) {
  if (prevRowMeta.indexOfValue(fieldName) < 0) {
    throw new KettleException("Field missing from input stream: " + fieldName);
  }
}

Try / catch

try { return processRow(row); } catch (KettleException e) { if (e.getMessage().contains("FieldNotFound")) { log.error("Add the missing field upstream: " + extractFieldName(e.getMessage())); } throw e; }

Prevention

When it happens

Trigger: A stream field listed in the step's 'stream field' mapping column was renamed or removed upstream in the transformation, so getInputRowMeta().indexOfValue(name) returns -1 on the first data row.

Common situations: Renaming a field in a Select Values/Calculator step without updating the upsert mapping; source column dropped when upstream file/API schema changed; case-sensitivity mismatch between the mapping and the actual field name.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

      // 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] ) );
        }
      }
    }

    try {
      writeToSalesForce( outputRowData );
    } catch ( Exception e ) {
      throw new KettleStepException( BaseMessages.getString( PKG, "SalesforceUpsert.log.Exception" ), e );
    }
    return true;
  }

  @VisibleForTesting
  void writeToSalesForce( Object[] rowData ) throws KettleException {
    try {

      if ( log.isDetailed() ) {

View on GitHub (pinned to f3058517a1)