pentaho/pentaho-kettle · error · KettleException

ProcessFiles.Error.TargetFilenameFieldMissing

Error message

ProcessFiles.Error.TargetFilenameFieldMissing

What it means

KettleException thrown by ProcessFiles.processRow on the first row when the 'target filename field' setting is empty and the operation is not DELETE. For copy/move operations the step needs both source and target filename fields; only DELETE can skip the target. The condition is operationType != OPERATION_TYPE_DELETE && Utils.isEmpty(getDynamicTargetFileNameField()).

Solutions

  1. Set 'Target filename fieldname' in the step dialog to a field containing the destination path.
  2. If the operation is intentionally DELETE, switch the operation type to Delete so the target field is not required.
  3. Call meta.setDynamicTargetFileNameField("target_file") when configuring via the API.

Example fix

// before
meta.setDynamicSourceFileNameField("src");
meta.setOperationType(ProcessFilesMeta.OPERATION_TYPE_MOVE); // throws
// after
meta.setDynamicSourceFileNameField("src");
meta.setDynamicTargetFileNameField("dst");
meta.setOperationType(ProcessFilesMeta.OPERATION_TYPE_MOVE);
Defensive patterns

Strategy: validation

Validate before calling

// Operation/field consistency check before execution
if (meta.getOperationType() != ProcessFilesMeta.OPERATION_TYPE_DELETE
    && (meta.getDynamicTargetFileNameField() == null || meta.getDynamicTargetFileNameField().isEmpty())) {
  throw new IllegalArgumentException("Process Files: target filename field required for non-delete operations");
}

Try / catch

try { trans.execute(null); } catch (KettleException e) { if (e.getMessage().contains("TargetFilenameFieldMissing")) { log.error("Set target filename field or use DELETE operation", e); } throw e; }

Prevention

When it happens

Trigger: Process Files step configured with operation type COPY, MOVE, or RENAME (i.e., any non-delete) while 'Target filename fieldname' is blank.

Common situations: User switches operation to Copy/Move after configuring only the source field; step built programmatically without setDynamicTargetFileNameField.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFiles.java:72

    meta = (ProcessFilesMeta) smi;
    data = (ProcessFilesData) sdi;

    Object[] r = getRow(); // Get row from input rowset & set row busy!
    if ( r == null ) { // no more input to be expected...

      setOutputDone();
      return false;
    }
    if ( first ) {
      first = false;
      // Check is source filename field is provided
      if ( Utils.isEmpty( meta.getDynamicSourceFileNameField() ) ) {
        throw new KettleException( BaseMessages.getString( PKG, "ProcessFiles.Error.SourceFilenameFieldMissing" ) );
      }
      // Check is target filename field is provided
      if ( meta.getOperationType() != ProcessFilesMeta.OPERATION_TYPE_DELETE
        && Utils.isEmpty( meta.getDynamicTargetFileNameField() ) ) {
        throw new KettleException( BaseMessages.getString( PKG, "ProcessFiles.Error.TargetFilenameFieldMissing" ) );
      }

      // cache the position of the source filename field
      if ( data.indexOfSourceFilename < 0 ) {
        data.indexOfSourceFilename = getInputRowMeta().indexOfValue( meta.getDynamicSourceFileNameField() );
        if ( data.indexOfSourceFilename < 0 ) {
          // The field is unreachable !
          throw new KettleException( BaseMessages.getString( PKG, "ProcessFiles.Exception.CouldnotFindField", meta
            .getDynamicSourceFileNameField() ) );
        }
      }
      // cache the position of the source filename field
      if ( meta.getOperationType() != ProcessFilesMeta.OPERATION_TYPE_DELETE && data.indexOfTargetFilename < 0 ) {
        data.indexOfTargetFilename = getInputRowMeta().indexOfValue( meta.getDynamicTargetFileNameField() );
        if ( data.indexOfTargetFilename < 0 ) {
          // The field is unreachable !
          throw new KettleException( BaseMessages.getString( PKG, "ProcessFiles.Exception.CouldnotFindField", meta
            .getDynamicTargetFileNameField() ) );

View on GitHub (pinned to f3058517a1)