pentaho/pentaho-kettle · error · KettleException
SalesforceDelete.Error.FlushBuffer
Error message
SalesforceDelete.Error.FlushBuffer
What it means
During flushBuffers, after executing the delete batch, the step inspects data.deleteResult for per-record failures. If the transformation is not doing error handling and a delete result contains an error, it throws a KettleException with the record index, the Salesforce status code (e.g. ENTITY_IS_DELETED, INVALID_CROSS_REFERENCE_KEY), and the error message from the first error.
Solutions
- Enable error handling on the Delete step so failed records are routed to an error stream instead of aborting the transformation
- Filter out already-deleted or invalid record IDs before the Delete step
- Check the Salesforce user's delete permissions and record access (sharing rules)
- Re-run only the failed records after fixing the root cause reported by the status code
Example fix
// before: no error handling, single failure aborts the run // step settings: error handling disabled // after: configure the step's error handling target so errors do not stop the transformation stepMeta.setSupportsErrorHandling(true); // and configure an error hop in Spoon
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check for already-deleted or inaccessible records where possible Set<String> existingIds = salesforceQueryExistingIds(candidateIds); List<String> deletable = candidateIds.stream().filter(existingIds::contains).collect(Collectors.toList());
Try / catch
try {
flushBuffers();
} catch (KettleException e) {
logError("Batch delete failed; enable error handling to capture per-record errors: " + e.getMessage());
throw e;
} Prevention
- Enable error handling on the Salesforce Delete step so per-record failures route to an error stream
- Filter out already-deleted records before deleting (idempotency check)
- Verify the integration user has Delete permission on the target object
- Log per-record status codes to identify systemic causes (locks, permissions, cross-reference keys)
When it happens
Trigger: A record in the delete batch failed on the Salesforce side: already deleted, locked, insufficient access, or invalid ID — and the step has no error handling configured, so the whole step aborts.
Common situations: Deleting records that were already removed (double-run of the transformation); records owned by another user without delete permission; master-detail records blocked by referential constraints; invalid record IDs in the input stream.
Related errors
- SalesforceDelete.FailedToDeleted
- SalesforceDelete.Error.CanNotFindFDeleteKeyField
- SalesforceDelete.Error.DeleteKeyFieldMissing
- SalesforceDelete.Error.WriteToSalesforce
- SalesforceDelete.log.Exception
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/e7f3de666b6fb600.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforcedelete/SalesforceDelete.java:159
if ( checkFeedback( getLinesInput() ) ) {
if ( log.isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "SalesforceDelete.log.LineRow", String
.valueOf( getLinesInput() ) ) );
}
}
} else {
// there were errors during the create call, go through the
// errors
// array and write them to the screen
if ( !getStepMeta().isDoingErrorHandling() ) {
if ( log.isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "SalesforceDelete.Found.Error" ) );
}
com.sforce.soap.partner.Error err = data.deleteResult[j].getErrors()[0];
throw new KettleException( BaseMessages
.getString( PKG, "SalesforceDelete.Error.FlushBuffer", new Integer( j ), err.getStatusCode(), err
.getMessage() ) );
}
String errorMessage = "";
int nrErrors = data.deleteResult[j].getErrors().length;
for ( int i = 0; i < nrErrors; i++ ) {
// get the next error
com.sforce.soap.partner.Error err = data.deleteResult[j].getErrors()[i];
errorMessage +=
BaseMessages.getString( PKG, "SalesforceDelete.Error.FlushBuffer", new Integer( j ), err
.getStatusCode(), err.getMessage() );
}
// Simply add this row to the error row
if ( log.isDebug() ) {
logDebug( BaseMessages.getString( PKG, "SalesforceDelete.PassingRowToErrorStep" ) );
}
putError( getInputRowMeta(), data.outputBuffer[j], 1, errorMessage, null, "SalesforceDelete001" );View on GitHub (pinned to f3058517a1)