{"record":{"id":"a80ff1520570f4b8","repo":"pentaho/pentaho-kettle","slug":"mail-log-replyfieldempty","errorCode":null,"errorMessage":"Mail.Log.ReplyFieldEmpty","messagePattern":"Mail\\.Log\\.ReplyFieldEmpty","errorType":"validation","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java","lineNumber":468,"sourceCode":"\n      if ( !meta.isZipFilenameDynamic() ) {\n        data.ZipFilename = environmentSubstitute( meta.getZipFilename() );\n      }\n      // Attached files\n      processAttachedFiles();\n    }\n  }\n\n  @VisibleForTesting\n  void validateMetaFields( MailMeta meta ) throws KettleException {\n    // Check is filename field is provided\n    if ( Utils.isEmpty( meta.getDestination() ) ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"Mail.Log.DestinationFieldEmpty\" ) );\n    }\n\n    // Check is replyname field is provided\n    if ( Utils.isEmpty( meta.getReplyAddress() ) ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"Mail.Log.ReplyFieldEmpty\" ) );\n    }\n\n    // Check is SMTP server is provided\n    if ( Utils.isEmpty( meta.getServer() ) ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"Mail.Log.ServerFieldEmpty\" ) );\n    }\n\n    // Check Attached filenames when dynamic\n    if ( meta.isDynamicFilename() && Utils.isEmpty( meta.getDynamicFieldname() ) ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"Mail.Log.DynamicFilenameFieldEmpty\" ) );\n    }\n\n    // Check Attached zipfilename when dynamic\n    if ( meta.isZipFilenameDynamic() && Utils.isEmpty( meta.getDynamicZipFilenameField() ) ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"Mail.Log.DynamicZipFilenameFieldEmpty\" ) );\n    }\n\n    validateZipFiles( meta );","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java#L450-L486","documentation":"Thrown by Mail.validateMetaFields when meta.getReplyAddress() is empty. The Mail step requires a reply address (the address recipients reply to) before processing rows, so it fails fast with this KettleException during processRow. It is metadata validation, not an SMTP error.","triggerScenarios":"Executing the Mail step with the 'Reply address' / reply-name field left blank in the step configuration; MailMeta built in code without setReplyAddress().","commonSituations":"Step dialog filled in except the reply section (users assume reply is optional); transformations copied from templates where the reply field was cleared; programmatic meta construction omitting setReplyAddress().","solutions":["Open the Mail step dialog and fill in the Reply address (and reply name) fields.","Call meta.setReplyAddress(\"reply@yourdomain.com\") when constructing MailMeta programmatically.","Re-export/re-save the transformation to ensure the reply-address setting persists in the XML."],"exampleFix":"// before\nmeta.setDestination(\"destField\");\n// after\nmeta.setDestination(\"destField\");\nmeta.setReplyAddress(\"reply@yourdomain.com\");","handlingStrategy":"validation","validationCode":"if ( meta.getReplyAddress() == null || meta.getReplyAddress().trim().isEmpty() ) {\n  throw new IllegalArgumentException(\"Mail step: reply address is required\");\n}","typeGuard":null,"tryCatchPattern":"try { transformation.execute(); } catch ( KettleException e ) { if ( e.getMessage().contains(\"ReplyFieldEmpty\") ) { /* set meta.setReplyAddress(...) and retry */ } else { throw e; } }","preventionTips":["Treat reply address as mandatory when configuring the Mail step","Keep a checklist of required Mail step fields (destination, reply, server)","Source reply addresses from kettle.properties variables and validate them at startup"],"tags":["kettle","mail-step","validation","configuration"],"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"}