pentaho/pentaho-kettle · error · KettleStepException

Unable to find field [

Error message

Unable to find field [

What it means

In PGBulkLoaderMeta.getSQLStatements(), each stream field name listed in the field mapping (fieldStream[i]) is looked up in the step's incoming row layout via prev.searchValueMeta(fieldStream[i]). If the name is not present in the input rows, a KettleStepException "Unable to find field [...] in the input rows" is thrown while generating the CREATE TABLE / SQL preview statements. It means the mapping references a field the upstream step never produces.

Solutions

  1. Open the PostgreSQL/GP bulk loader's 'Fields' tab and re-select the stream field so it matches the actual upstream field name.
  2. Inspect the previous step's output fields (preview/GET FIELDS) and align the mapping names exactly (case-sensitive).
  3. If upstream changed intentionally, update or delete the stale mapping row; use 'Get fields' to auto-populate the mapping.

Example fix

// before (mapping references old name)
fieldStream = new String[] { "cust_nm" };
// after: rebuild mapping from actual incoming layout
RowMetaInterface prev = transMeta.getPrevStepFields( stepMeta );
fieldStream = new String[] { prev.searchValueMeta( "customer_name" ) != null ? "customer_name" : ... };
Defensive patterns

Strategy: validation

Validate before calling

RowMetaInterface prev = transMeta.getPrevStepFields( stepMeta );
for ( String f : fieldStream ) {
  if ( prev.searchValueMeta( f ) == null ) throw new KettleStepException( "Field not in input rows: " + f );
}

Try / catch

try { sqlStatements = meta.getSQLStatements( transMeta, stepMeta, prev ); } catch ( KettleStepException e ) { /* re-open step dialog, refresh field mapping */ }

Prevention

When it happens

Trigger: getSQLStatements() is called (e.g. from the transformation's SQL button) while fieldStream[i] — a mapped incoming field name — does not match any ValueMeta in the previous step's row output: the field was renamed or removed upstream, the mapping was edited after upstream changes, or the mapping was injected with stale names.

Common situations: Renaming a field in a Select Values / Text File Input step without updating the bulk loader mapping; copying a transformation between environments where upstream schemas differ; metadata injection supplying outdated FIELDSTREAM names; typo in the mapped stream field name.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/24de07981c19c09d. Report an issue: GitHub.

Appendix: source

Thrown at plugins/postgresql-db-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/pgbulkloader/PGBulkLoaderMeta.java:514

  public SQLStatement getSQLStatements( TransMeta transMeta, StepMeta stepMeta, RowMetaInterface prev,
    Repository repository, IMetaStore metaStore ) throws KettleStepException {
    SQLStatement retval = new SQLStatement( stepMeta.getName(), databaseMeta, null ); // default: nothing to do!

    if ( databaseMeta != null ) {
      if ( prev != null && prev.size() > 0 ) {
        // Copy the row
        RowMetaInterface tableFields = new RowMeta();

        // Now change the field names
        for ( int i = 0; i < fieldTable.length; i++ ) {
          ValueMetaInterface v = prev.searchValueMeta( fieldStream[i] );
          if ( v != null ) {
            ValueMetaInterface tableField = v.clone();
            tableField.setName( fieldTable[i] );
            tableFields.addValueMeta( tableField );
          } else {
            throw new KettleStepException( "Unable to find field [" + fieldStream[i] + "] in the input rows" );
          }
        }

        if ( !Utils.isEmpty( tableName ) ) {
          Database db = new Database( loggingObject, databaseMeta );
          db.shareVariablesWith( transMeta );
          try {
            db.connect();

            String schemaTable =
              databaseMeta.getQuotedSchemaTableCombination(
                transMeta.environmentSubstitute( schemaName ), transMeta.environmentSubstitute( tableName ) );
            String sql = db.getDDL( schemaTable, tableFields, null, false, null, true );

            if ( sql.length() == 0 ) {
              retval.setSQL( null );
            } else {
              retval.setSQL( sql );

View on GitHub (pinned to f3058517a1)