pentaho/pentaho-kettle · error · KettleException

Error updating batch, first 10 errors: Errors encountered…

Error message

Error updating batch, first 10 errors: Errors encountered (first 10):

What it means

Thrown after a KettleDatabaseBatchException escapes lookupValues(): when the step is NOT doing row-level error handling, it catches the batch exception, collects messages from the first 10 wrapped exceptions, and rethrows a KettleException titled 'Error updating batch, first 10 errors: Errors encountered (first 10):' so the user can see the individual batch failures.

Solutions

  1. Read the 10 appended messages to identify the common failing cause (constraint, datatype, size).
  2. Configure error handling on the step (define an error hop) so bad rows are captured instead of aborting the transformation.
  3. Fix the data or target schema issues named in the individual batch error messages.
  4. Reduce batch size so fewer rows fail together and errors are easier to isolate.
Defensive patterns

Strategy: try-catch

Try / catch

catch (KettleException e) {
  if (e.getMessage().startsWith("Error updating batch")) {
    Throwable cause = e.getCause();
    if (cause instanceof KettleDatabaseBatchException) {
      ((KettleDatabaseBatchException) cause).getExceptionsList()
        .forEach(ex -> logError("Batch row error: " + ex.getMessage()));
    }
  }
}

Prevention

When it happens

Trigger: lookupValues() threw KettleDatabaseBatchException from executeBatch(); in the outer catch, getStepMeta().isDoingErrorHandling() is false, so the code builds msg from be.getExceptionsList() and throws KettleException(msg, be).

Common situations: Multiple rows in one batch violate constraints or types; user has no error-handling hops configured so the whole transformation fails instead of routing bad rows; inspecting which rows failed.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/0da201593d490c4d. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java:424

      }
      if ( data.deleteStatement != null ) {
        data.db.clearBatch( data.deleteStatement );
      }

      if ( getStepMeta().isDoingErrorHandling() ) {
        data.db.commit( true );
      } else {
        data.db.rollback();
        StringBuilder msg = new StringBuilder( "Error batch inserting rows into table [" + data.realTableName + "]." );
        msg.append( Const.CR );
        msg.append( "Errors encountered (first 10):" ).append( Const.CR );
        for (int x = 0; x < be.getExceptionsList().size() && x < 10; x++) {
          Exception exception = be.getExceptionsList().get( x );
          if ( exception.getMessage() != null ) {
            msg.append( exception.getMessage() ).append( Const.CR );
          }
        }
        throw new KettleException( msg.toString(), be );
      }
    } catch ( KettleDatabaseException dbe ) {
      if ( getStepMeta().isDoingErrorHandling() ) {
        if ( log.isRowLevel() ) {
          logRowlevel( "Written row to error handling : " + getInputRowMeta().getString( row ) );
        }

        if ( data.specialErrorHandling && data.supportsSavepoints ) {
          if ( data.savepoint != null || !data.lookupFailure ) {
            // do this when savepoint was set, and this is not lookup failure PDI-10878
            data.db.rollback( data.savepoint );
            if ( data.releaseSavepoint ) {
              data.db.releaseSavepoint( data.savepoint );
            }
          }
        }
        sendToErrorRow = true;
        errorMessage = dbe.toString();

View on GitHub (pinned to f3058517a1)