{"record":{"id":"a9d176f03e930630","repo":"pentaho/pentaho-kettle","slug":"execsql-log-errorinstep","errorCode":"ExecSQL.Log.ErrorInStep","errorMessage":"ExecSQL.Log.ErrorInStep","messagePattern":"ExecSQL\\.Log\\.ErrorInStep","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/sql/ExecSQL.java","lineNumber":229,"sourceCode":"      row = RowDataUtil.addRowData( row, getInputRowMeta().size(), add.getData() );\n\n      if ( !data.db.isAutoCommit() ) {\n        data.db.commit();\n      }\n\n      putRow( data.outputRowMeta, row ); // send it out!\n\n      if ( checkFeedback( getLinesWritten() ) ) {\n        if ( log.isBasic() ) {\n          logBasic( BaseMessages.getString( PKG, \"ExecSQL.Log.LineNumber\" ) + getLinesWritten() );\n        }\n      }\n    } catch ( KettleException e ) {\n      if ( getStepMeta().isDoingErrorHandling() ) {\n        sendToErrorRow = true;\n        errorMessage = e.toString();\n      } else {\n        throw new KettleStepException( BaseMessages.getString( PKG, \"ExecSQL.Log.ErrorInStep\" ), e );\n      }\n\n      if ( sendToErrorRow ) {\n        // Simply add this row to the error row\n        putError( getInputRowMeta(), row, 1, errorMessage, null, \"ExecSQL001\" );\n      }\n    }\n    return true;\n  }\n\n  @Override\n  public void dispose( StepMetaInterface smi, StepDataInterface sdi ) {\n    meta = (ExecSQLMeta) smi;\n    data = (ExecSQLData) sdi;\n\n    if ( log.isBasic() ) {\n      logBasic( BaseMessages.getString( PKG, \"ExecSQL.Log.FinishingReadingQuery\" ) );\n    }","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/sql/ExecSQL.java#L211-L247","documentation":"Generic error wrapper thrown by ExecSQL.processRow when the step's work (executing SQL per row) throws a KettleException and the step is NOT configured with error handling. If error handling is enabled the exception is instead routed to the error row stream; without it, it becomes a KettleStepException with message 'ExecSQL.Log.ErrorInStep' and the SQL failure as cause.","triggerScenarios":"Any SQL execution failure during processRow — invalid SQL statement, database connection failure, constraint violation, missing table — combined with no error-handling step attached to ExecSQL.","commonSituations":"SQL syntax errors after editing the SQL template; database credentials expired; target table dropped; deadlock or timeout on large executions; forgetting to attach an error hop so failures abort the transformation.","solutions":["Read the wrapped cause for the actual SQL/database error","Fix the SQL statement or database state indicated by the cause","Attach an error handling step (error hop) to route failing rows instead of aborting","Verify the database connection defined in the ExecSQL step (test + credentials)","Enable 'execute for each row' / parameter binding correctness to avoid SQL injection/format errors"],"exampleFix":"// before: no error handling -> step aborts on SQL failure\n// after (design-time fix): attach an error hop\nexecSqlStep.getStepMeta().setDoingErrorHandling(true);\nexecSqlStep.addErrorHop(targetErrorLogStep);\n// rows failing SQL go to the error stream instead of throwing","handlingStrategy":"try-catch","validationCode":"// design-time: verify SQL and connection\nif (execSqlMeta.getDatabaseMeta() == null) throw new IllegalStateException(\"ExecSQL connection missing\");\n// test the SQL manually against the target DB before running the transformation","typeGuard":null,"tryCatchPattern":"try { trans.execute(null); trans.waitUntilFinished(); if (trans.getErrors() > 0) { /* read step log for ExecSQL.Log.ErrorInStep cause */ } } catch (KettleException e) { logError(\"ExecSQL failed: \" + e.getCause()); }","preventionTips":["Attach an error-handling step so row-level SQL failures don't abort the transformation","Test SQL statements and credentials before deployment","Use parameter binding (arguments) instead of string concatenation","Monitor DB connection limits and timeouts"],"tags":["sql","step-execution","error-handling"],"backgroundTag":"sql-query-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}