pentaho/pentaho-kettle · error · KettleException
Error inserting row into table
Error message
Error inserting row into table [<tableName>] with values: <row>
What it means
Thrown in lookupValues()'s catch of KettleDatabaseException when the step is not doing row-level error handling: the step rolls back the transaction and rethrows a KettleException naming the target table and the full offending input row, so the developer sees exactly which row and table caused the insert/update/delete to fail.
Solutions
- Inspect the wrapped KettleDatabaseException cause (dbe) for the actual SQL error and fix the data/schema issue.
- Compare the printed row values against the target table column definitions for type/length mismatches.
- Enable error handling on the step to route failing rows to an error stream instead of failing the whole transformation.
- Verify the connection user has INSERT/UPDATE/DELETE privileges on the target table.
Example fix
// before: stream field String into NUMBER column // after: add a 'Select values' step converting the field to Integer before SynchronizeAfterMerge
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate row fits target schema
if (rowValue.length(targetColumn) > columnMaxLen) {
throw new ValidationException("Value too long for column: " + targetColumn);
} Try / catch
catch (KettleException e) {
if (e.getMessage().startsWith("Error inserting row into table")) {
logError("Row failed: " + e.getMessage() + "; cause: " + e.getCause());
}
throw e;
} Prevention
- Match stream field types and lengths to target column definitions.
- Grant the connection user required DML privileges.
- Enable error handling to capture failing rows instead of rolling back the whole run.
When it happens
Trigger: A KettleDatabaseException (SQLException from executing the DML for the current row) is caught; getStepMeta().isDoingErrorHandling() is false; the code increments errors, rolls back data.db, and throws with data.realTableName and data.inputRowMeta.getString(row).
Common situations: Constraint violations (PK/unique/FK/not null), value too long for column, type mismatch between stream field and column, table dropped or renamed, permission denied on the target table.
Related errors
- SynchronizeAfterMerge.Error.UpdatingBatch
- AddSequence.Exception.ErrorReadingSequence
- An error occurred executing SQL:
- Couldn't execute SQL:
- Couldn't find any rows because of an error :
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/e2a15919e975955f.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/synchronizeaftermerge/SynchronizeAfterMerge.java:446
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();
} else {
setErrors( getErrors() + 1 );
data.db.rollback();
throw new KettleException( "Error inserting row into table [" + data.realTableName + "] with values: "
+ data.inputRowMeta.getString( row ), dbe );
}
}
if ( data.batchMode ) {
if ( sendToErrorRow ) {
if ( batchProblem ) {
data.batchBuffer.add( row );
processBatchException( errorMessage, updateCounts, exceptionsList );
} else {
// Simply add this row to the error row
putError( data.inputRowMeta, row, 1L, errorMessage, null, "SUYNC002" );
}
} else {
if ( !lineSkipped ) {
data.batchBuffer.add( row );
}
View on GitHub (pinned to f3058517a1)