pentaho/pentaho-kettle · error · KettleException

JobGetMailsFromPOP.Error.AttachmentFolderEmpty

Error message

JobGetMailsFromPOP.Error.AttachmentFolderEmpty

What it means

createOutputDirectory(FOLDER_ATTACHMENTS) throws this KettleException when the resolved attachments folder path is empty. Attachments extracted from fetched mails need a target directory; an empty one aborts the entry before any mail is processed.

Solutions

  1. Fill in the 'Attachments directory' field with a valid absolute path.
  2. Define any variable used for the attachments directory before the job runs.
  3. Disable attachment saving (uncheck include attachments) if attachments are not needed, so the field is irrelevant.

Example fix

// before (kjb XML)
<attachment_folder></attachment_folder>
// after
<attachment_folder>/data/pentaho/mail_attachments</attachment_folder>
Defensive patterns

Strategy: validation

Validate before calling

String att = environmentSubstitute(getAttachmentFolder());
if (includeAttachments() && (att == null || att.trim().isEmpty())) {
  throw new IllegalArgumentException("Attachments folder must be set when saving attachments");
}

Try / catch

try { executeJobEntry(); } catch (KettleException e) {
  if (e.getMessage().contains("AttachmentFolderEmpty")) {
    logError("Attachments directory is empty; set attachment_folder or disable attachment saving");
  } else { throw e; }
}

Prevention

When it happens

Trigger: execute() -> createOutputDirectory(FOLDER_ATTACHMENTS) with Utils.isEmpty(folderName) true: the attachments directory field is blank or its variable resolves to empty string.

Common situations: 'Attachments directory' left blank even though 'include attachments' is selected; variable ${ATTACH_DIR} undefined at runtime; entry copied from a template where the field was cleared.

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/94cf222382c4806c. Report an issue: GitHub.

Appendix: source

Thrown at plugins/email-messages/impl/src/main/java/org/pentaho/di/job/entries/getpop/JobEntryGetPOP.java:1582

    String folderName = "";
    switch ( folderType ) {
      case JobEntryGetPOP.FOLDER_OUTPUT:
        folderName = getRealOutputDirectory();
        break;
      case JobEntryGetPOP.FOLDER_ATTACHMENTS:
        if ( isSaveAttachment() && isDifferentFolderForAttachment() ) {
          folderName = getRealAttachmentFolder();
        } else {
          folderName = getRealOutputDirectory();
        }
        break;
    }
    if ( Utils.isEmpty( folderName ) ) {
      switch ( folderType ) {
        case JobEntryGetPOP.FOLDER_OUTPUT:
          throw new KettleException( BaseMessages.getString( PKG, "JobGetMailsFromPOP.Error.OutputFolderEmpty" ) );
        case JobEntryGetPOP.FOLDER_ATTACHMENTS:
          throw new KettleException( BaseMessages.getString( PKG, "JobGetMailsFromPOP.Error.AttachmentFolderEmpty" ) );
      }
    }
    FileObject folder = KettleVFS.getInstance( parentJobMeta.getBowl() ).getFileObject( folderName, this );
    if ( folder.exists() ) {
      if ( folder.getType() != FileType.FOLDER ) {
        switch ( folderType ) {
          case JobEntryGetPOP.FOLDER_OUTPUT:
            throw new KettleException( BaseMessages.getString(
              PKG, "JobGetMailsFromPOP.Error.NotAFolderNot", folderName ) );
          case JobEntryGetPOP.FOLDER_ATTACHMENTS:
            throw new KettleException( BaseMessages.getString(
              PKG, "JobGetMailsFromPOP.Error.AttachmentFolderNotAFolder", folderName ) );
        }
      }
      if ( isDebug() ) {
        switch ( folderType ) {
          case JobEntryGetPOP.FOLDER_OUTPUT:
            logDebug( BaseMessages.getString( PKG, "JobGetMailsFromPOP.Log.OutputFolderExists", folderName ) );

View on GitHub (pinned to f3058517a1)