{"record":{"id":"c7a41d4663c155b8","repo":"pentaho/pentaho-kettle","slug":"processfiles-error-targetfilenamefieldmissing","errorCode":null,"errorMessage":"ProcessFiles.Error.TargetFilenameFieldMissing","messagePattern":"ProcessFiles\\.Error\\.TargetFilenameFieldMissing","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFiles.java","lineNumber":72,"sourceCode":"    meta = (ProcessFilesMeta) smi;\n    data = (ProcessFilesData) sdi;\n\n    Object[] r = getRow(); // Get row from input rowset & set row busy!\n    if ( r == null ) { // no more input to be expected...\n\n      setOutputDone();\n      return false;\n    }\n    if ( first ) {\n      first = false;\n      // Check is source filename field is provided\n      if ( Utils.isEmpty( meta.getDynamicSourceFileNameField() ) ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"ProcessFiles.Error.SourceFilenameFieldMissing\" ) );\n      }\n      // Check is target filename field is provided\n      if ( meta.getOperationType() != ProcessFilesMeta.OPERATION_TYPE_DELETE\n        && Utils.isEmpty( meta.getDynamicTargetFileNameField() ) ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"ProcessFiles.Error.TargetFilenameFieldMissing\" ) );\n      }\n\n      // cache the position of the source filename field\n      if ( data.indexOfSourceFilename < 0 ) {\n        data.indexOfSourceFilename = getInputRowMeta().indexOfValue( meta.getDynamicSourceFileNameField() );\n        if ( data.indexOfSourceFilename < 0 ) {\n          // The field is unreachable !\n          throw new KettleException( BaseMessages.getString( PKG, \"ProcessFiles.Exception.CouldnotFindField\", meta\n            .getDynamicSourceFileNameField() ) );\n        }\n      }\n      // cache the position of the source filename field\n      if ( meta.getOperationType() != ProcessFilesMeta.OPERATION_TYPE_DELETE && data.indexOfTargetFilename < 0 ) {\n        data.indexOfTargetFilename = getInputRowMeta().indexOfValue( meta.getDynamicTargetFileNameField() );\n        if ( data.indexOfTargetFilename < 0 ) {\n          // The field is unreachable !\n          throw new KettleException( BaseMessages.getString( PKG, \"ProcessFiles.Exception.CouldnotFindField\", meta\n            .getDynamicTargetFileNameField() ) );","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/processfiles/ProcessFiles.java#L54-L90","documentation":"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()).","triggerScenarios":"Process Files step configured with operation type COPY, MOVE, or RENAME (i.e., any non-delete) while 'Target filename fieldname' is blank.","commonSituations":"User switches operation to Copy/Move after configuring only the source field; step built programmatically without setDynamicTargetFileNameField.","solutions":["Set 'Target filename fieldname' in the step dialog to a field containing the destination path.","If the operation is intentionally DELETE, switch the operation type to Delete so the target field is not required.","Call meta.setDynamicTargetFileNameField(\"target_file\") when configuring via the API."],"exampleFix":"// before\nmeta.setDynamicSourceFileNameField(\"src\");\nmeta.setOperationType(ProcessFilesMeta.OPERATION_TYPE_MOVE); // throws\n// after\nmeta.setDynamicSourceFileNameField(\"src\");\nmeta.setDynamicTargetFileNameField(\"dst\");\nmeta.setOperationType(ProcessFilesMeta.OPERATION_TYPE_MOVE);","handlingStrategy":"validation","validationCode":"// Operation/field consistency check before execution\nif (meta.getOperationType() != ProcessFilesMeta.OPERATION_TYPE_DELETE\n    && (meta.getDynamicTargetFileNameField() == null || meta.getDynamicTargetFileNameField().isEmpty())) {\n  throw new IllegalArgumentException(\"Process Files: target filename field required for non-delete operations\");\n}","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Recheck step settings after changing operation type","Use Delete operation only when target field is intentionally omitted","Programmatic meta builders: set both fields unconditionally"],"tags":["kettle","configuration","file-processing"],"backgroundTag":"missing-required-config-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"}