pentaho/pentaho-kettle · error · KettleException
SalesforceUpsert.FailedInWrite
Error message
SalesforceUpsert.FailedInWrite
What it means
Thrown in SalesforceUpsert.writeToSalesForce when an unexpected (non-Kettle) exception escapes the buffer/flush logic. Unlike KettleExceptions (rethrown as-is), generic Exceptions are wrapped with this message containing e.toString(). It usually means the write to Salesforce failed in an unforeseen way.
Solutions
- Read e.toString() in the message to identify the wrapped root exception.
- Check for null values in fields mapped as external IDs — set them to empty-safe defaults or filter those rows first.
- Validate that stream field data types match the target Salesforce field types (string vs number vs date).
- Enable error handling on the step to divert failing rows and inspect them.
Example fix
// before: null external-id value causes NPE downstream
if (row[fieldNr] == null) throw new KettleException("null ext id");
// after: substitute a safe value before the upsert step
// Use 'If field value is null' / NVL: NVL(externalIdField, "MISSING_ID") Defensive patterns
Strategy: validation
Validate before calling
for (String extIdField : meta.getUpdateStream()) {
int idx = inputRowMeta.indexOfValue(extIdField);
if (idx >= 0 && rowData[idx] == null) {
throw new KettleException("Null value in external-ID mapped field: " + extIdField);
}
} Try / catch
try { writeToSalesForce(rowData); } catch (KettleException e) { if (!e.getMessage().contains("FailedInWrite")) throw e; log.error("Wrapped write failure: " + e.getMessage()); sendRowToErrorStream(rowData, e); } Prevention
- Replace nulls in external-ID columns with NVL before the step
- Validate field data types against Salesforce field types
- Enable step error handling to capture failing rows
When it happens
Trigger: Any RuntimeException or checked non-Kettle exception while building SObjects or flushing buffers — e.g. NullPointerException when a mapped stream field value is null for an external-ID field, class-cast issues, or SOAP client faults.
Common situations: Null values in fields mapped to Salesforce external IDs; type conversions between Kettle values and SObject fields; Salesforce WSC library errors; unexpected nulls in upsert key columns.
Related errors
- SalesforceUpsert.Error.FlushBuffer
- SalesforceUpsert.FailedUpsert
- SalesforceUpsertDialog.FieldsMissing.DialogMessage
- SalesforceConnection.UnableToFindObjectType
- SalesforceUpdateMeta.Exception.ErrorReadingRepository
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/848c34201d24f060.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforceupsert/SalesforceUpsert.java:179
// Set Null to fields
sobjPass.setFieldsToNull( fieldsToNull.toArray( new String[fieldsToNull.size()] ) );
}
// Load the buffer array
data.sfBuffer[data.iBufferPos] = sobjPass;
data.outputBuffer[data.iBufferPos] = rowData;
data.iBufferPos++;
}
if ( data.iBufferPos >= meta.getBatchSizeInt() ) {
if ( log.isDetailed() ) {
logDetailed( "Calling flush buffer from writeToSalesForce" );
}
flushBuffers();
}
} catch ( KettleException ke ) {
throw ke;
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "SalesforceUpsert.FailedInWrite", e.toString() ) );
}
}
void setFieldInSObject( SObject sobjPass, XmlObject element ) {
Iterator<XmlObject> children = element.getChildren();
String name = element.getName().getLocalPart();
if ( !children.hasNext() ) {
sobjPass.setSObjectField( name, element.getValue() );
} else {
SObject child = new SObject();
child.setName( new QName( name ) );
while ( children.hasNext() ) {
setFieldInSObject( child, children.next() );
}
sobjPass.setSObjectField( name, child );
}
}
View on GitHub (pinned to f3058517a1)