{"record":{"id":"d7f3e114490a4401","repo":"pentaho/pentaho-kettle","slug":"mail-log-destinationfieldempty","errorCode":null,"errorMessage":"Mail.Log.DestinationFieldEmpty","messagePattern":"Mail\\.Log\\.DestinationFieldEmpty","errorType":"validation","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java","lineNumber":463,"sourceCode":"      }\n      data.zipFileLimit = Const.toLong( environmentSubstitute( meta.getZipLimitSize() ), 0 );\n      if ( data.zipFileLimit > 0 ) {\n        data.zipFileLimit = data.zipFileLimit * 1048576; // Mo\n      }\n\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","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java#L445-L481","documentation":"The Pentaho Kettle Mail step throws this when the transformation metadata has no destination field configured. validateMetaFields, called at the start of processRow, checks meta.getDestination() with Utils.isEmpty and aborts the step because the mail step cannot determine the recipient(s) without it. It is a fail-fast metadata validation before any row processing or SMTP activity.","triggerScenarios":"Running the Mail transformation step with the 'Destination' (to-address / destination field) setting left empty in the step dialog; the destination field name in MailMeta is blank or null when processRow invokes validateMetaFields.","commonSituations":"Importing a transformation from another environment where the Mail step dialog was partially filled; cloning a step and deleting the destination field; building MailMeta programmatically and forgetting setDestination(); upgrading jobs where the field mapping was lost.","solutions":["Open the Mail step dialog and set the Destination field (or the field name holding the destination addresses).","If constructing MailMeta in code, call meta.setDestination(\"YourFieldOrAddress\") before executing.","Verify the transformation XML exports the destination attribute correctly; re-save the step and re-export.","If recipients are genuinely not needed, ensure this is the intended behavior — the step requires a destination unconditionally."],"exampleFix":"// before (programmatic MailMeta)\nMailMeta meta = new MailMeta();\nmeta.setReplyAddress(\"reply@corp.com\");\n// after\nMailMeta meta = new MailMeta();\nmeta.setDestination(\"destField\");\nmeta.setReplyAddress(\"reply@corp.com\");","handlingStrategy":"validation","validationCode":"// Before executing the transformation, check the metadata\nif ( meta.getDestination() == null || meta.getDestination().trim().isEmpty() ) {\n  throw new IllegalArgumentException(\"Mail step: destination field is required\");\n}","typeGuard":null,"tryCatchPattern":"try { transformation.execute(); } catch ( KettleException e ) { if ( e.getMessage().contains(\"DestinationFieldEmpty\") ) { /* reconfigure MailMeta.setDestination */ } else { throw e; } }","preventionTips":["Always set destination when building MailMeta programmatically","Re-save the Mail step after importing transformations to validate all fields","Add a metadata job entry that validates required step fields before production runs"],"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"}