pentaho/pentaho-kettle · error · KettleException

GetSubFolders.Exception.CouldnotFindField

Error message

GetSubFolders.Exception.CouldnotFindField

What it means

GetSubFolders.processRow throws KettleException 'CouldnotFindField' (with the resolved field name) when the configured dynamic folder-name field is not present in the incoming row's RowMeta. The environment-substituted field name is looked up via indexOfValue and returns -1, so the step cannot locate the folder path per row.

Solutions

  1. Correct the field name in the step dialog to match the incoming row exactly (case-sensitive).
  2. Check the variable value used in the field name resolves as expected (Ctrl+Shift+K / set variables).
  3. Inspect the upstream row layout (Preview) and reconnect/update the step accordingly.
  4. Re-order steps so the field exists before Get SubFolders runs.

Example fix

// before
meta.setDynamicFoldernameField( "folder_name " ); // trailing space
// after
meta.setDynamicFoldernameField( "folder_name" ); // matches RowMeta
Defensive patterns

Strategy: validation

Validate before calling

// Verify the field exists in the incoming row before execution
RowMetaInterface in = transMeta.getPrevStepFields( stepMeta );
String field = environmentSubstitute( meta.getDynamicFoldernameField() );
if ( field == null || in.indexOfValue( field ) < 0 )
  throw new IllegalStateException( "Field not in stream: " + field );

Try / catch

try {
  trans.execute( null );
} catch ( KettleException e ) {
  if ( e.getMessage() != null && e.getMessage().contains( "CouldnotFindField" ) ) {
    // log the offending field name from the message and fix the step/upstream
  } else throw e;
}

Prevention

When it happens

Trigger: indexOfFoldernameField < 0 after indexOfValue(realDynamicFoldername); field name typo, field removed upstream, or variables in the field name resolving to the wrong name.

Common situations: Renaming an upstream Select values field without updating this step; using ${VAR} in the field name that doesn't resolve; connecting the step to a different hop than intended.

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/fd75e9d09b6b20c0. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/getsubfolders/GetSubFolders.java:102

        // Get total previous fields
        data.totalpreviousfields = data.inputRowMeta.size();

        // Check is filename field is provided
        if ( Utils.isEmpty( meta.getDynamicFoldernameField() ) ) {
          logError( BaseMessages.getString( PKG, "GetSubFolders.Log.NoField" ) );
          throw new KettleException( BaseMessages.getString( PKG, "GetSubFolders.Log.NoField" ) );
        }

        // cache the position of the field
        if ( data.indexOfFoldernameField < 0 ) {
          String realDynamicFoldername = environmentSubstitute( meta.getDynamicFoldernameField() );
          data.indexOfFoldernameField = data.inputRowMeta.indexOfValue( realDynamicFoldername );
          if ( data.indexOfFoldernameField < 0 ) {
            // The field is unreachable !
            logError( BaseMessages.getString( PKG, "GetSubFolders.Log.ErrorFindingField" )
              + "[" + realDynamicFoldername + "]" );
            throw new KettleException( BaseMessages.getString(
              PKG, "GetSubFolders.Exception.CouldnotFindField", realDynamicFoldername ) );
          }
        }
      } else {
        // Create the output row meta-data
        data.outputRowMeta = new RowMeta();
        meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
          metaStore );
        // data.nrStepFields= data.outputRowMeta.size();

        data.files = meta.getFolderList( getTransMeta().getBowl(), this );
        data.filessize = data.files.nrOfFiles();
        handleMissingFiles();

      }
      data.nrStepFields = data.outputRowMeta.size();

    } // end if first

View on GitHub (pinned to f3058517a1)