{"record":{"id":"dec9f2e00c419627","repo":"pentaho/pentaho-kettle","slug":"execsqlrow-error-sqlfieldfieldmissing","errorCode":null,"errorMessage":"ExecSQLRow.Error.SQLFieldFieldMissing","messagePattern":"ExecSQLRow\\.Error\\.SQLFieldFieldMissing","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/execsqlrow/ExecSQLRow.java","lineNumber":103,"sourceCode":"\n    Object[] row = getRow();\n    if ( row == null ) { // no more input to be expected...\n\n      setOutputDone();\n      return false;\n    }\n\n    if ( first ) { // we just got started\n\n      first = false;\n\n      data.outputRowMeta = getInputRowMeta().clone();\n      meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,\n        metaStore );\n\n      // Check is SQL field is provided\n      if ( Utils.isEmpty( meta.getSqlFieldName() ) ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"ExecSQLRow.Error.SQLFieldFieldMissing\" ) );\n      }\n\n      // cache the position of the field\n      if ( data.indexOfSQLFieldname < 0 ) {\n        data.indexOfSQLFieldname = this.getInputRowMeta().indexOfValue( meta.getSqlFieldName() );\n        if ( data.indexOfSQLFieldname < 0 ) {\n          // The field is unreachable !\n          throw new KettleException( BaseMessages.getString( PKG, \"ExecSQLRow.Exception.CouldnotFindField\", meta\n            .getSqlFieldName() ) );\n        }\n      }\n\n    }\n\n    // get SQL\n    String sql = getInputRowMeta().getString( row, data.indexOfSQLFieldname );\n\n    try {","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/execsqlrow/ExecSQLRow.java#L85-L121","documentation":"KettleException thrown by ExecSQLRow.processRow() when the step's 'SQL field name' setting (meta.getSqlFieldName()) is empty. The step executes SQL statements taken from a field of the incoming row, so it requires that field name to be configured before processing.","triggerScenarios":"Executing a transformation with an 'Execute SQL script' (ExecSQLRow) step whose 'sql field name' was never set in the step dialog, and processRow() calls Utils.isEmpty(meta.getSqlFieldName()) which returns true.","commonSituations":"Step metadata lost or not saved properly; transformation built programmatically without calling setSqlFieldName; legacy XML loaded where the sql field attribute was blank.","solutions":["Open the Execute SQL script step in Spoon and set the 'SQL field name' to an existing field of the incoming stream.","Programmatically, call setSqlFieldName(\"theField\") on the ExecSQLRowMeta before running.","Verify the step metadata persisted correctly (check the ktr XML for the sql_field tag)."],"exampleFix":"// before\nExecSQLRowMeta meta = new ExecSQLRowMeta();\nmeta.setDatabaseMeta(dbMeta); // sqlFieldName never set\n// after\nExecSQLRowMeta meta = new ExecSQLRowMeta();\nmeta.setDatabaseMeta(dbMeta);\nmeta.setSqlFieldName(\"sql_statement\"); // must match an incoming field","handlingStrategy":"validation","validationCode":"if (meta.getSqlFieldName() == null || meta.getSqlFieldName().isEmpty()) {\n  throw new IllegalStateException(\"ExecSQLRow: SQL field name must be set\");\n}","typeGuard":null,"tryCatchPattern":"try { trans.execute(...); } catch (KettleException e) { if (e.getMessage().contains(\"SQLFieldFieldMissing\")) { /* reconfigure step */ } }","preventionTips":["Always set sqlFieldName when building ExecSQLRowMeta programmatically","Verify persisted ktr XML contains the sql field attribute","Use step check() remarks before running"],"tags":["configuration","sql","kettle"],"backgroundTag":"missing-required-config-field","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"}