pentaho/pentaho-kettle · error · KettleException
Failed in writeToSalesForce:
Error message
Failed in writeToSalesForce:
What it means
writeToSalesForce() wraps its buffer management and flush logic in a try/catch and rethrows as KettleException('\\nFailed in writeToSalesForce: ' + e.getMessage()). It aggregates any failure while preparing or flushing the Salesforce update batch. Note it keeps only e.getMessage(), so the exception class and stack are lost — a known debugging pain point.
Solutions
- Read the appended message after 'Failed in writeToSalesForce:' for the root Salesforce error text.
- Check step log output at detailed level for the specific SObject row being written.
- Validate field values/types sent to Salesforce (nulls, external-ID fields) — see errors 3747/3748 for the underlying flush failures.
- If diagnostics are unclear, enable detailed logging or patch the catch to pass the whole exception as cause.
Example fix
// before: cause and stacktrace are dropped throw new KettleException( "\nFailed in writeToSalesForce: " + e.getMessage() ); // after: keep the cause for diagnosis throw new KettleException( "\nFailed in writeToSalesForce", e );
Defensive patterns
Strategy: try-catch
Validate before calling
// Sanity-check batchSize and field data before executing the step
if (meta.getBatchSizeInt() <= 0 || meta.getBatchSizeInt() > 10000) {
throw new IllegalArgumentException("Invalid batchSize: " + meta.getBatchSizeInt());
} Try / catch
try {
step.processRow();
} catch (KettleException e) {
// message is 'Failed in writeToSalesForce: <root msg>' — parse and also check step logs
log.error("writeToSalesForce failure: {}", e.getMessage());
} Prevention
- Enable detailed logging on the step to capture per-row context the message drops.
- Keep batchSize moderate to avoid oversized Salesforce requests.
- Prefer fixed builds where the cause is preserved (the catch drops the stacktrace).
- Validate field values (nulls, Id formats) before the batch is built.
When it happens
Trigger: Called from processRow per row (and from unit tests): exceptions while adding an SObject to the buffer or calling flushBuffers() — Salesforce API errors, connection failures, or internal NPEs.
Common situations: Batch update failing because of Salesforce API limits or bad field data; session timeout mid-batch; misconfigured batchSize leading to oversized requests.
Related errors
- Erreur getting fields from module [
- Error getting fields from module [
- Field [ ] couldn't be found in the input stream!
- \nFailed to update object, error message was: \n
- SalesforceConnection.Exception.Query
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/64fcbde4c4a7c730.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforceupdate/SalesforceUpdate.java:166
if ( fieldsToNull.size() > 0 ) {
// 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 ( Exception e ) {
throw new KettleException( "\nFailed in writeToSalesForce: " + e.getMessage() );
}
}
private void flushBuffers() throws KettleException {
try {
if ( data.sfBuffer.length > data.iBufferPos ) {
SObject[] smallBuffer = new SObject[data.iBufferPos];
System.arraycopy( data.sfBuffer, 0, smallBuffer, 0, data.iBufferPos );
data.sfBuffer = smallBuffer;
}
// update the object(s) by sending the array to the web service
data.saveResult = data.connection.update( data.sfBuffer );
int nr = data.saveResult.length;
for ( int j = 0; j < nr; j++ ) {
if ( data.saveResult[j].isSuccess() ) {
// Row was updated
String id = data.saveResult[j].getId();View on GitHub (pinned to f3058517a1)