pentaho/pentaho-kettle · error · KettleException

Mail.Log.DynamicFilenameFieldEmpty

Error message

Mail.Log.DynamicFilenameFieldEmpty

What it means

Thrown by Mail.validateMetaFields when the step is configured for dynamic attachment filenames (meta.isDynamicFilename() is true) but meta.getDynamicFieldname() — the incoming row field that supplies the attachment filename — is empty. The step cannot know which row field to read attachment paths from, so it aborts. This pairs with error 3199, which fires when the named field is set but absent from the row.

Solutions

  1. In the Mail step dialog, select the incoming field that contains the attachment filename in the dynamic-filename field dropdown.
  2. Call meta.setDynamicFieldname("attachmentPathField") in code whenever setDynamicFilename(true) is used.
  3. If dynamic attachments are not needed, disable the dynamic filename option instead of leaving the field blank.

Example fix

// before
meta.setDynamicFilename(true);
// after
meta.setDynamicFilename(true);
meta.setDynamicFieldname("attachmentPath");
Defensive patterns

Strategy: validation

Validate before calling

if ( meta.isDynamicFilename() && ( meta.getDynamicFieldname() == null || meta.getDynamicFieldname().trim().isEmpty() ) ) {
  throw new IllegalArgumentException("Mail step: dynamic filename field must be selected");
}

Try / catch

try { transformation.execute(); } catch ( KettleException e ) { if ( e.getMessage().contains("DynamicFilenameFieldEmpty") ) { /* enable/set setDynamicFieldname or disable dynamic mode */ } else { throw e; } }

Prevention

When it happens

Trigger: Checking 'dynamic filename' for attachments in the Mail step but leaving the source-filename-field dropdown empty; MailMeta built in code with setDynamicFilename(true) but no setDynamicFieldname(...).

Common situations: Switching a step from static to dynamic attachments and forgetting to pick the field; the field dropdown reset after XML edits; programmatic meta construction enabling dynamic mode without naming the field.

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


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

Appendix: source

Thrown at plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java:478

  void validateMetaFields( MailMeta meta ) throws KettleException {
    // Check is filename field is provided
    if ( Utils.isEmpty( meta.getDestination() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.DestinationFieldEmpty" ) );
    }

    // Check is replyname field is provided
    if ( Utils.isEmpty( meta.getReplyAddress() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.ReplyFieldEmpty" ) );
    }

    // Check is SMTP server is provided
    if ( Utils.isEmpty( meta.getServer() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.ServerFieldEmpty" ) );
    }

    // Check Attached filenames when dynamic
    if ( meta.isDynamicFilename() && Utils.isEmpty( meta.getDynamicFieldname() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.DynamicFilenameFieldEmpty" ) );
    }

    // Check Attached zipfilename when dynamic
    if ( meta.isZipFilenameDynamic() && Utils.isEmpty( meta.getDynamicZipFilenameField() ) ) {
      throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.DynamicZipFilenameFieldEmpty" ) );
    }

    validateZipFiles( meta );

    // check authentication
    if ( meta.isUsingAuthentication().equals( AUTENTICATION_BASIC ) ) {
      // check authentication user
      if ( Utils.isEmpty( meta.getAuthenticationUser() ) ) {
        throw new KettleException( BaseMessages.getString( PKG, "Mail.Log.AuthenticationUserFieldEmpty" ) );
      }

      // check authentication pass
      if ( Utils.isEmpty( meta.getAuthenticationPassword() ) ) {

View on GitHub (pinned to f3058517a1)