pentaho/pentaho-kettle · error · KettleException
ProcessFiles.Error.SourceFileEmpty
Error message
ProcessFiles.Error.SourceFileEmpty
What it means
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.
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.
Example fix
// before: passing rows straight into ProcessFiles ProcessFiles(sourceField='filename') // after FilterRows(field='filename', operator='IS NOT NULL AND <> ""') -> ProcessFiles(sourceField='filename')
Defensive patterns
Strategy: validation
Validate before calling
// Filter rows step condition before ProcessFiles: ISNOTNULL( [sourceFilename] ) && [sourceFilename] <> ""
Type guard
boolean hasSourceFilename(Object[] row, RowMetaInterface meta, String field) {
int i = meta.indexOfValue(field);
return i >= 0 && row[i] != null && !row[i].toString().trim().isEmpty();
} Try / catch
try {
processRow();
} catch (KettleException e) {
if (e.getMessage().contains("SourceFileEmpty")) {
logError("Row has empty source filename; routing to error stream");
} else throw e;
} Prevention
- 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
When it happens
Trigger: getInputRowMeta().getString(r, data.indexOfSourceFilename) returns null or "" for some row; Utils.isEmpty(sourceFilename) is true.
Common situations: 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.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- ProcessFiles.Error.TargetFileEmpty
- ProcessFiles.Error.SourceFileNotFile
- WebServiceAvailable.Error.URLEmpty
- API coding error: please specify the conversion metadata…
- Calculator.Error.NoNameField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/727a850fa6d95a4e.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFiles.java:106
// The field is unreachable !
throw new KettleException( BaseMessages.getString( PKG, "ProcessFiles.Exception.CouldnotFindField", meta
.getDynamicTargetFileNameField() ) );
}
}
if ( meta.simulate ) {
if ( log.isBasic() ) {
logBasic( BaseMessages.getString( PKG, "ProcessFiles.Log.SimulationModeON" ) );
}
}
} // End If first
try {
// get source filename
String sourceFilename = getInputRowMeta().getString( r, data.indexOfSourceFilename );
if ( Utils.isEmpty( sourceFilename ) ) {
logError( BaseMessages.getString( PKG, "ProcessFiles.Error.SourceFileEmpty" ) );
throw new KettleException( BaseMessages.getString( PKG, "ProcessFiles.Error.SourceFileEmpty" ) );
}
data.sourceFile = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( sourceFilename, getTransMeta() );
if ( !data.sourceFile.exists() ) {
logError( BaseMessages.getString( PKG, "ProcessFiles.Error.SourceFileNotExist", sourceFilename ) );
throw new KettleException( BaseMessages.getString(
PKG, "ProcessFiles.Error.SourceFileNotExist", sourceFilename ) );
}
if ( data.sourceFile.getType() != FileType.FILE ) {
logError( BaseMessages.getString( PKG, "ProcessFiles.Error.SourceFileNotFile", sourceFilename ) );
throw new KettleException( BaseMessages.getString(
PKG, "ProcessFiles.Error.SourceFileNotFile", sourceFilename ) );
}
String targetFilename = null;
if ( meta.getOperationType() != ProcessFilesMeta.OPERATION_TYPE_DELETE ) {
// get value for target filename
targetFilename = getInputRowMeta().getString( r, data.indexOfTargetFilename );
View on GitHub (pinned to f3058517a1)