{"record":{"id":"727a850fa6d95a4e","repo":"pentaho/pentaho-kettle","slug":"processfiles-error-sourcefileempty","errorCode":null,"errorMessage":"ProcessFiles.Error.SourceFileEmpty","messagePattern":"ProcessFiles\\.Error\\.SourceFileEmpty","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFiles.java","lineNumber":106,"sourceCode":"          // The field is unreachable !\n          throw new KettleException( BaseMessages.getString( PKG, \"ProcessFiles.Exception.CouldnotFindField\", meta\n            .getDynamicTargetFileNameField() ) );\n        }\n      }\n\n      if ( meta.simulate ) {\n        if ( log.isBasic() ) {\n          logBasic( BaseMessages.getString( PKG, \"ProcessFiles.Log.SimulationModeON\" ) );\n        }\n      }\n    } // End If first\n    try {\n      // get source filename\n      String sourceFilename = getInputRowMeta().getString( r, data.indexOfSourceFilename );\n\n      if ( Utils.isEmpty( sourceFilename ) ) {\n        logError( BaseMessages.getString( PKG, \"ProcessFiles.Error.SourceFileEmpty\" ) );\n        throw new KettleException( BaseMessages.getString( PKG, \"ProcessFiles.Error.SourceFileEmpty\" ) );\n      }\n      data.sourceFile = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( sourceFilename, getTransMeta() );\n\n      if ( !data.sourceFile.exists() ) {\n        logError( BaseMessages.getString( PKG, \"ProcessFiles.Error.SourceFileNotExist\", sourceFilename ) );\n        throw new KettleException( BaseMessages.getString(\n          PKG, \"ProcessFiles.Error.SourceFileNotExist\", sourceFilename ) );\n      }\n      if ( data.sourceFile.getType() != FileType.FILE ) {\n        logError( BaseMessages.getString( PKG, \"ProcessFiles.Error.SourceFileNotFile\", sourceFilename ) );\n        throw new KettleException( BaseMessages.getString(\n          PKG, \"ProcessFiles.Error.SourceFileNotFile\", sourceFilename ) );\n      }\n      String targetFilename = null;\n      if ( meta.getOperationType() != ProcessFilesMeta.OPERATION_TYPE_DELETE ) {\n        // get value for target filename\n        targetFilename = getInputRowMeta().getString( r, data.indexOfTargetFilename );\n","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFiles.java#L88-L124","documentation":"Thrown when the value of the source filename field in the current row is null or empty. Pentaho throws it because it cannot resolve a VFS FileObject for an empty path and proceeding would produce misleading downstream failures.","triggerScenarios":"getInputRowMeta().getString(r, data.indexOfSourceFilename) returns null or \"\" for some row; Utils.isEmpty(sourceFilename) is true.","commonSituations":"Upstream source produced null filename for rows outside the expected set; database column with NULL path values; a filter step removed rows but not the empty ones; text file input with missing column values.","solutions":["Add a 'Filter rows' step before ProcessFiles to drop rows where the source filename field is null or empty.","Fix the upstream step that generates the filename so it always emits a valid path.","Use a 'Value Mapper' or 'If field value is null' step to supply a default filename.","Enable error handling on the ProcessFiles step and route empty-filename rows to a separate stream."],"exampleFix":"// before: passing rows straight into ProcessFiles\nProcessFiles(sourceField='filename')\n// after\nFilterRows(field='filename', operator='IS NOT NULL AND <> \"\"') -> ProcessFiles(sourceField='filename')","handlingStrategy":"validation","validationCode":"// Filter rows step condition before ProcessFiles:\nISNOTNULL( [sourceFilename] ) && [sourceFilename] <> \"\"","typeGuard":"boolean hasSourceFilename(Object[] row, RowMetaInterface meta, String field) {\n  int i = meta.indexOfValue(field);\n  return i >= 0 && row[i] != null && !row[i].toString().trim().isEmpty();\n}","tryCatchPattern":"try {\n  processRow();\n} catch (KettleException e) {\n  if (e.getMessage().contains(\"SourceFileEmpty\")) {\n    logError(\"Row has empty source filename; routing to error stream\");\n  } else throw e;\n}","preventionTips":["Filter NULL/empty filename rows upstream","Give database path columns NOT NULL constraints or COALESCE defaults","Preview rows before the step to spot empty values early","Use step error handling to divert bad rows instead of failing the transformation"],"tags":["pdi","kettle","empty-value","file-processing"],"backgroundTag":"empty-required-field","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"}