{"record":{"id":"dd7d4a7cf853e9da","repo":"pentaho/pentaho-kettle","slug":"processfiles-error-targetparentfoldernotexists","errorCode":null,"errorMessage":"ProcessFiles.Error.TargetParentFolderNotExists","messagePattern":"ProcessFiles\\.Error\\.TargetParentFolderNotExists","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFiles.java","lineNumber":146,"sourceCode":"        }\n        data.targetFile = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( targetFilename, getTransMeta() );\n        if ( data.targetFile.exists() ) {\n          if ( log.isDetailed() ) {\n            logDetailed( BaseMessages.getString( PKG, \"ProcessFiles.Log.TargetFileExists\", targetFilename ) );\n          }\n          // check if target is really a file otherwise it could overwrite a complete folder by copy or move operations\n          if ( data.targetFile.getType() != FileType.FILE ) {\n            logError( BaseMessages.getString( PKG, \"ProcessFiles.Error.TargetFileNotFile\", targetFilename ) );\n            throw new KettleException( BaseMessages.getString(\n              PKG, \"ProcessFiles.Error.TargetFileNotFile\", targetFilename ) );\n          }\n\n        } else {\n          // let's check parent folder\n          FileObject parentFolder = data.targetFile.getParent();\n          if ( !parentFolder.exists() ) {\n            if ( !meta.isCreateParentFolder() ) {\n              throw new KettleException( BaseMessages.getString(\n                PKG, \"ProcessFiles.Error.TargetParentFolderNotExists\", parentFolder.toString() ) );\n            } else {\n              parentFolder.createFolder();\n            }\n          }\n          if ( parentFolder != null ) {\n            parentFolder.close();\n          }\n        }\n      }\n\n      switch ( meta.getOperationType() ) {\n        case ProcessFilesMeta.OPERATION_TYPE_COPY:\n          if ( ( ( meta.isOverwriteTargetFile() && data.targetFile.exists() ) || !data.targetFile.exists() )\n            && !meta.simulate ) {\n            data.targetFile.copyFrom( data.sourceFile, new TextOneToOneFileSelector() );\n            if ( log.isDetailed() ) {\n              logDetailed( BaseMessages.getString(","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFiles.java#L128-L164","documentation":"Thrown when the target file's parent folder does not exist and the 'Create parent folder' option is disabled. Pentaho refuses to write/move the file into a nonexistent directory rather than silently creating it.","triggerScenarios":"Operation Copy/Move; data.targetFile.exists() is false; parentFolder.exists() is false; meta.isCreateParentFolder() is false.","commonSituations":"Target directory tree not created before the transformation runs; timestamped/dynamic folder names (e.g. /out/2026/09/13) that don't exist yet; deploy difference between dev and prod environments where folders were created manually.","solutions":["Enable 'Create parent folder' checkbox in the ProcessFiles step dialog.","Create the target directory beforehand with a job entry (e.g. 'Create a folder' or shell mkdir -p).","Fix the target path expression if the parent folder name is accidentally wrong (typo, wrong env variable).","Use error handling to catch the failure and create the folder in a recovery path."],"exampleFix":"// before (step XML)\n<create_parent_folder>N</create_parent_folder>\n// after\n<create_parent_folder>Y</create_parent_folder>","handlingStrategy":"validation","validationCode":"// Guard: parent folder must exist (or be creatable) before ProcessFiles\njava.io.File parent = new java.io.File(targetFilename).getParentFile();\nboolean ok = parent != null && (parent.exists() || parent.mkdirs());","typeGuard":"boolean parentFolderReady(String targetPath) {\n  java.io.File p = (targetPath == null) ? null : new java.io.File(targetPath).getParentFile();\n  return p != null && p.isDirectory();\n}","tryCatchPattern":"try {\n  processRow();\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"TargetParentFolderNotExists\")) {\n    logError(\"Enable 'Create parent folder' or create: \" + extractPath(e));\n  } else throw e;\n}","preventionTips":["Check 'Create parent folder' in the step dialog when using dynamic target paths","Pre-create target directories in the job before the transformation","Validate environment variables used in folder paths per environment","Test dynamic (e.g. date-based) folder expressions before production runs"],"tags":["pdi","kettle","directory-not-found","configuration"],"backgroundTag":"directory-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"}