pentaho/pentaho-kettle · error · KettleException

GetSubFolders.Exception.MissingFiles

GetSubFolders.Exception.MissingFiles

Error message

GetSubFolders.Exception.MissingFiles

What it means

GetSubFolders.handleMissingFiles throws KettleException 'MissingFiles' when any configured folder/file path does not exist after the file list was built. FileInputList reports non-existent FileObjects, their descriptions are joined into the message, and the step aborts. This enforces 'fail if missing' semantics instead of silently processing nothing.

Solutions

  1. Verify every folder path in the step exists on the executing machine.
  2. Resolve the variables/parameters used in the paths and confirm their runtime values.
  3. Enable 'Include subfolders'/wildcards correctly or remove stale entries from the folder list.
  4. Use 'Fail if file exists?'-style checks in a preceding step or a Check if file exists step to guard paths.

Example fix

// before: path resolved from unset variable
String folder = "${DATA_DIR}/input"; // DATA_DIR unset -> /input missing
// after: set the variable before run
String folder = "/data/prod/input"; // or pass -param:DATA_DIR=/data/prod
Defensive patterns

Strategy: validation

Validate before calling

// Check all configured folders exist and are readable before the run
for ( String folder : meta.getFolderName() ) {
  String real = transMeta.environmentSubstitute( folder );
  File f = new File( real );
  if ( !f.exists() ) throw new IllegalStateException( "Folder does not exist: " + real );
}

Try / catch

try {
  trans.execute( null );
} catch ( KettleException e ) {
  if ( e.getMessage() != null && e.getMessage().contains( "MissingFiles" ) ) {
    // parse missing paths from message, fix variables/paths, re-run
  } else throw e;
}

Prevention

When it happens

Trigger: handleMissingFiles (from processRow) finds data.files.getNonExistantFiles() non-empty: a configured folder path, wildcard base, or variable-resolved path points to something absent at run time.

Common situations: Running the transformation on another machine where mapped drives/paths don't exist; variables or parameters pointing to environment-specific folders not set; folders deleted between design and run; case-sensitive Linux paths differing from Windows.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

    data.filenr++;

    if ( checkFeedback( getLinesInput() ) ) {
      if ( log.isBasic() ) {
        logBasic( BaseMessages.getString( PKG, "GetSubFolders.Log.NrLine", "" + getLinesInput() ) );
      }
    }

    return true;
  }

  private void handleMissingFiles() throws KettleException {
    List<FileObject> nonExistantFiles = data.files.getNonExistantFiles();

    if ( nonExistantFiles.size() != 0 ) {
      String message = FileInputList.getRequiredFilesDescription( nonExistantFiles );
      logError( BaseMessages.getString( PKG, "GetSubFolders.Error.MissingFiles", message ) );
      throw new KettleException( BaseMessages.getString( PKG, "GetSubFolders.Exception.MissingFiles", message ) );
    }

    List<FileObject> nonAccessibleFiles = data.files.getNonAccessibleFiles();
    if ( nonAccessibleFiles.size() != 0 ) {
      String message = FileInputList.getRequiredFilesDescription( nonAccessibleFiles );
      logError( BaseMessages.getString( PKG, "GetSubFolders.Error.NoAccessibleFiles", message ) );
      throw new KettleException( BaseMessages
        .getString( PKG, "GetSubFolders.Exception.NoAccessibleFiles", message ) );
    }
  }

  public boolean init( StepMetaInterface smi, StepDataInterface sdi ) {
    meta = (GetSubFoldersMeta) smi;
    data = (GetSubFoldersData) sdi;

    if ( super.init( smi, sdi ) ) {
      //Set Embedded NamedCluter MetatStore Provider Key so that it can be passed to VFS
      if ( getTransMeta().getNamedClusterEmbedManager() != null ) {

View on GitHub (pinned to f3058517a1)