pentaho/pentaho-kettle · error · KettleException
DynamicSQLRow.Exception.FieldNotFound
Error message
DynamicSQLRow.Exception.FieldNotFound
What it means
On the first row, DynamicSQLRow.processRow resolves the configured SQL field name to an index in the input row metadata; if the field is absent from the incoming row it throws this KettleException saying the field is unreachable. The step cannot extract the SQL statement from the row without it.
Solutions
- Set the 'SQL fieldname' in the step dialog to a field that actually exists upstream
- Add/repair the upstream step (e.g. 'Add constants', JavaScript) to produce the SQL text field
- Check with a 'Stream lookup'/preview that the field name matches exactly (case included)
- Re-save and re-run after upstream changes
Example fix
// before step configured with sql fieldname 'query' but upstream emits 'sql_text' // after configure sql fieldname = 'sql_text' (matching the upstream field)
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the configured field exists in the incoming stream:
String field = meta.getSQLFieldName();
if (field == null || inputRowMeta.indexOfValue(field) < 0) {
throw new IllegalStateException("Field '" + field + "' not present in input stream");
} Try / catch
try {
lookupValues(inputRowMeta, row);
} catch (KettleException e) {
logError("SQL field not found in input: check upstream steps", e);
stopAll(); setErrors(1);
return false;
} Prevention
- Preview the previous step and match the field name exactly (case-sensitive)
- Avoid renaming/removing the field upstream without updating this step
- Keep the SQL-text-producing step adjacent in the flow
- Run transformation checks (Hop: verify) before executing
When it happens
Trigger: At runtime when getInputRowMeta().indexOfValue(sqlFieldName) returns -1 — the field named in the step settings is not present in the row arriving from the previous step (renamed, removed, or wrong name configured).
Common situations: Upstream step renamed or dropped the field; typo in the SQL fieldname setting; inserting a Select values step that removes the field; case-sensitivity differences.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- AutoDoc.Exception.FilenameFieldNotFound
- AutoDoc.Exception.FileTypeFieldNotFound
- GetTableNames.Exception.CouldnotFindField
- HTTP.Exception.CouldnotFindField
- HTTP.Exception.ErrorFindingField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/6cc9d1bf2c2455c8.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/dynamicsqlrow/DynamicSQLRow.java:230
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() );
}
}
} catch ( KettleException e ) {
boolean sendToErrorRow = false;
String errorMessage = null;
if ( getStepMeta().isDoingErrorHandling() ) {
sendToErrorRow = true;View on GitHub (pinned to f3058517a1)