{"record":{"id":"99032cb9ca0c2d6d","repo":"pentaho/pentaho-kettle","slug":"getsubfolders-exception-missingfiles","errorCode":"GetSubFolders.Exception.MissingFiles","errorMessage":"GetSubFolders.Exception.MissingFiles","messagePattern":"GetSubFolders\\.Exception\\.MissingFiles","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/getsubfolders/GetSubFolders.java","lineNumber":229,"sourceCode":"\n    data.filenr++;\n\n    if ( checkFeedback( getLinesInput() ) ) {\n      if ( log.isBasic() ) {\n        logBasic( BaseMessages.getString( PKG, \"GetSubFolders.Log.NrLine\", \"\" + getLinesInput() ) );\n      }\n    }\n\n    return true;\n  }\n\n  private void handleMissingFiles() throws KettleException {\n    List<FileObject> nonExistantFiles = data.files.getNonExistantFiles();\n\n    if ( nonExistantFiles.size() != 0 ) {\n      String message = FileInputList.getRequiredFilesDescription( nonExistantFiles );\n      logError( BaseMessages.getString( PKG, \"GetSubFolders.Error.MissingFiles\", message ) );\n      throw new KettleException( BaseMessages.getString( PKG, \"GetSubFolders.Exception.MissingFiles\", message ) );\n    }\n\n    List<FileObject> nonAccessibleFiles = data.files.getNonAccessibleFiles();\n    if ( nonAccessibleFiles.size() != 0 ) {\n      String message = FileInputList.getRequiredFilesDescription( nonAccessibleFiles );\n      logError( BaseMessages.getString( PKG, \"GetSubFolders.Error.NoAccessibleFiles\", message ) );\n      throw new KettleException( BaseMessages\n        .getString( PKG, \"GetSubFolders.Exception.NoAccessibleFiles\", message ) );\n    }\n  }\n\n  public boolean init( StepMetaInterface smi, StepDataInterface sdi ) {\n    meta = (GetSubFoldersMeta) smi;\n    data = (GetSubFoldersData) sdi;\n\n    if ( super.init( smi, sdi ) ) {\n      //Set Embedded NamedCluter MetatStore Provider Key so that it can be passed to VFS\n      if ( getTransMeta().getNamedClusterEmbedManager() != null ) {","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/getsubfolders/GetSubFolders.java#L211-L247","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify every folder path in the step exists on the executing machine.","Resolve the variables/parameters used in the paths and confirm their runtime values.","Enable 'Include subfolders'/wildcards correctly or remove stale entries from the folder list.","Use 'Fail if file exists?'-style checks in a preceding step or a Check if file exists step to guard paths."],"exampleFix":"// before: path resolved from unset variable\nString folder = \"${DATA_DIR}/input\"; // DATA_DIR unset -> /input missing\n// after: set the variable before run\nString folder = \"/data/prod/input\"; // or pass -param:DATA_DIR=/data/prod","handlingStrategy":"validation","validationCode":"// Check all configured folders exist and are readable before the run\nfor ( String folder : meta.getFolderName() ) {\n  String real = transMeta.environmentSubstitute( folder );\n  File f = new File( real );\n  if ( !f.exists() ) throw new IllegalStateException( \"Folder does not exist: \" + real );\n}","typeGuard":null,"tryCatchPattern":"try {\n  trans.execute( null );\n} catch ( KettleException e ) {\n  if ( e.getMessage() != null && e.getMessage().contains( \"MissingFiles\" ) ) {\n    // parse missing paths from message, fix variables/paths, re-run\n  } else throw e;\n}","preventionTips":["Use environment variables consistently and set them per environment","Prefer relative paths under a known root with the variable set","Add a 'Check if file exists' or validation step before file-processing steps","Test transformations on the target execution host"],"tags":["kettle","pdi","filesystem","file"],"backgroundTag":"file-not-found","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"}