pentaho/pentaho-kettle · error · KettleException
DynamicSQLRow.Exception.SQLEmpty
Error message
DynamicSQLRow.Exception.SQLEmpty
What it means
DynamicSQLRow.processRow validates on the first row that the step's configured SQL template (meta.getSql()) is non-empty and throws this KettleException otherwise. Without a base SQL template the step has nothing to execute.
Solutions
- Open the step dialog and enter the SQL template (use ? placeholders as needed)
- Confirm the template is saved in the step XML (<sql> tag)
- Re-save the transformation after entering the SQL
- If SQL should come entirely from the field, still provide a minimal template consistent with the step's design
Example fix
// before <sql></sql> // after <sql>SELECT id, name FROM customers WHERE region = ?</sql>
Defensive patterns
Strategy: validation
Validate before calling
if (meta.getSql() == null || meta.getSql().trim().isEmpty()) {
throw new IllegalStateException("Dynamic SQL Row: SQL template is empty");
} Try / catch
try {
// processRow validation
} catch (KettleException e) {
logError("Enter the SQL template in the Dynamic SQL Row step", e);
stopAll(); setErrors(1);
return false;
} Prevention
- Never save the step with an empty SQL box
- Keep SQL templates in version control alongside the .ktr
- Verify <sql> tag content after importing/merging transformations
- Preview the step to confirm configuration loads correctly
When it happens
Trigger: Executing a Dynamic SQL Row step whose 'SQL' text box was left empty in the dialog, or whose saved metadata lost the sql attribute.
Common situations: Step added but never configured; XML/repository record with an empty <sql> tag; template accidentally cleared while editing the transformation.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- ExecSQLRow.Error.SQLFieldFieldMissing
- SQLFileOutputMeta.Exception.TableNotSpecified
- The tablename is not defined (empty)
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/df14691d5908e68c.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/dynamicsqlrow/DynamicSQLRow.java:222
}
public boolean processRow( StepMetaInterface smi, StepDataInterface sdi ) throws KettleException {
meta = (DynamicSQLRowMeta) smi;
data = (DynamicSQLRowData) sdi;
Object[] r = getRow(); // Get row from input rowset & set row busy!
if ( r == null ) { // no more input to be expected...
setOutputDone();
return false;
}
if ( first ) {
if ( Utils.isEmpty( meta.getSQLFieldName() ) ) {
throw new KettleException( BaseMessages.getString( PKG, "DynamicSQLRow.Exception.SQLFieldNameEmpty" ) );
}
if ( Utils.isEmpty( meta.getSql() ) ) {
throw new KettleException( BaseMessages.getString( PKG, "DynamicSQLRow.Exception.SQLEmpty" ) );
}
// cache the position of the field
if ( data.indexOfSQLField < 0 ) {
data.indexOfSQLField = getInputRowMeta().indexOfValue( meta.getSQLFieldName() );
if ( data.indexOfSQLField < 0 ) {
// The field is unreachable !
throw new KettleException( BaseMessages.getString( PKG, "DynamicSQLRow.Exception.FieldNotFound", meta
.getSQLFieldName() ) );
}
}
}
try {
lookupValues( getInputRowMeta(), r );
if ( checkFeedback( getLinesRead() ) ) {
if ( log.isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "DynamicSQLRow.Log.LineNumber" ) + getLinesRead() );View on GitHub (pinned to f3058517a1)