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

  1. Enable error handling on the Delete step so failed records are routed to an error stream instead of aborting the transformation
  2. Filter out already-deleted or invalid record IDs before the Delete step
  3. Check the Salesforce user's delete permissions and record access (sharing rules)
  4. 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

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


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)