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
- Read the message's field name and add/restore that field on the stream feeding the upsert step.
- Open the Salesforce Upsert dialog and update the mapping to an existing incoming field name.
- Check upstream steps (Select Values, filter, renamed CSV headers) that may have removed or renamed the column.
- 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
- Pin field names with a 'Field exists' check or Select Values step upstream
- Update the upsert mapping whenever upstream field names change
- Match field name casing exactly
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
- BaseStep.SafeMode.Exception.DoubleFieldnames
- BaseStep.SafeMode.Exception.MixingLayout
- BaseStep.SafeMode.Exception.MixingStorageTypes
- BaseStep.SafeMode.Exception.MixingTypes
- BaseStep.SafeMode.Exception.VaryingSize
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)