pentaho/pentaho-kettle · error · KettleException
SalesforceInput.ErrorUpsert
Error message
SalesforceInput.ErrorUpsert
What it means
KettleException thrown by SalesforceConnection.upsert() when the SOAP upsert call fails. Note the original exception is embedded in the MESSAGE (BaseMessages.getString(PKG, key, e)) rather than as a cause, so the Salesforce fault text appears directly in the error message. It means none/some of the upserted records were processed at the API transport level.
Solutions
- Read the embedded Salesforce fault in the message — it names the exact field/record problem
- Verify the upsertField is a real External ID / custom field marked unique and external
- Check integration user has Create and Update object permissions
- Validate data formats (dates, picklists, numbers) against the object's field types
- Retry with a smaller batch to isolate record-lock/timeout issues
Example fix
// before
UpsertResult[] r = connection.upsert("ExtId__c", buffer); // field not external id
// after
// In Salesforce setup, mark ExtId__c as External ID + unique, then:
UpsertResult[] r = connection.upsert("ExtId__c", buffer);
for (UpsertResult res : r) if (!res.isSuccess()) logInsertErrors(res.getErrors()); Defensive patterns
Strategy: validation
Validate before calling
if (upsertField == null || upsertField.isEmpty()) throw new IllegalArgumentException("External ID field required for upsert"); if (sfBuffer == null || sfBuffer.length == 0) throw new IllegalArgumentException("Empty upsert buffer"); Type guard
boolean upsertReady(String extField, SObject[] buf) { return extField != null && !extField.isEmpty() && buf != null && buf.length > 0; } Try / catch
try { results = connection.upsert(upsertField, buffer); } catch (KettleException e) { log.logError("Upsert failed: " + e.getMessage(), e); throw e; } // fault text is in e.getMessage() Prevention
- Mark the external-id field as External ID + unique in Salesforce setup
- Verify Create/Update permissions for the integration user
- Validate row data types against Salesforce field metadata before upsert
- Process in smaller batches to avoid lock timeouts and partial failures
- Iterate UpsertResult[] and log per-record errors even on success
When it happens
Trigger: Calling upsert(upsertField, sfBuffer) when the binding throws: invalid external-id field, session invalid, SObject malformed, or Salesforce rejecting the batch (e.g. field infeasible for upsert).
Common situations: External ID field not marked as external ID in Salesforce, missing Write/Create permission, record-lock contention during mass upserts, malformed data types (bad date/number formats) in the incoming rows.
Related errors
- SalesforceInput.ErrorDelete
- SalesforceInput.ErrorInsert
- SalesforceInput.ErrorUpdate
- Erreur getting fields from module [
- Error getting fields from module [
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/b202ab16b6c6fdba.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforce/SalesforceConnection.java:863
for ( Field f : referenceObjectFields ) {
if ( f.isIdLookup() && !isIdField( f ) ) {
fieldsList.add( String.format( "%s:%s/%s", referenceTo, f.getName(), field.getRelationshipName() ) );
}
}
}
}
return fieldsList.toArray( new String[fieldsList.size()] );
}
return null;
}
public UpsertResult[] upsert( String upsertField, SObject[] sfBuffer ) throws KettleException {
try {
return getBinding().upsert( upsertField, sfBuffer );
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.ErrorUpsert", e ) );
}
}
public SaveResult[] insert( SObject[] sfBuffer ) throws KettleException {
try {
List<SObject> normalizedSfBuffer = new ArrayList<>();
for ( SObject part : sfBuffer ) {
if ( part != null ) {
normalizedSfBuffer.add( part );
}
}
return getBinding().create( normalizedSfBuffer.toArray( new SObject[normalizedSfBuffer.size()] ) );
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.ErrorInsert", e ) );
}
}
public SaveResult[] update( SObject[] sfBuffer ) throws KettleException {View on GitHub (pinned to f3058517a1)