pentaho/pentaho-kettle · error · KettleException

Mail.Exception.CouldnotSourceAttachedFilenameField

Error message

Mail.Exception.CouldnotSourceAttachedFilenameField

What it means

Thrown by Mail.cacheSourceFileNameField when the configured dynamic attachment-filename field (meta.getDynamicFieldname()) is not found in the incoming row: previousRowMeta.indexOfValue returns -1. The setting is non-empty (that check is error 3193) but names a column the rowset does not contain, so the step cannot locate attachment paths and aborts.

Solutions

  1. Correct the dynamic-filename field in the Mail step dialog to an actual incoming column name (exact, case-sensitive).
  2. Ensure the upstream step emits the attachment-path column (add via Select Values if needed).
  3. After upstream schema changes, re-open and re-save the Mail step to refresh field references.
  4. Inspect available columns by logging rowMeta.getFieldNames() immediately before the Mail step.

Example fix

// before
meta.setDynamicFieldname("attachmentFile"); // column no longer exists in row
// after
meta.setDynamicFieldname("attachment_path"); // actual incoming column name
int idx = data.previousRowMeta.indexOfValue(meta.getDynamicFieldname()); // >= 0
Defensive patterns

Strategy: validation

Validate before calling

// Verify the dynamic attachment filename field exists in the incoming row
int idx = rowMeta.indexOfValue( meta.getDynamicFieldname() );
if ( idx < 0 ) {
  throw new IllegalArgumentException("Attachment filename field '" + meta.getDynamicFieldname() + "' not in row: "
    + Arrays.toString( rowMeta.getFieldNames() ) );
}

Try / catch

try { transformation.execute(); } catch ( KettleException e ) { if ( e.getMessage().contains("CouldnotSourceAttachedFilenameField") ) { /* correct meta.setDynamicFieldname to a real column */ } else { throw e; } }

Prevention

When it happens

Trigger: The dynamic filename field name in MailMeta does not match any column in the row arriving at the Mail step (typo, rename, dropped column upstream, case mismatch); processAttachedFiles triggers field caching on the first processed row.

Common situations: Renaming a field in an upstream Text File Input or Table Input step without updating the Mail step; transformations assembled from templates where field names differ; a hop changed so the Mail step now receives rows lacking the attachment column.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

  private void cacheWildCardField() throws KettleException {
    if ( !Utils.isEmpty( meta.getDynamicWildcard() ) ) {
      if ( data.indexOfSourceWildcard < 0 ) {
        String realSourceAttachedWildcard = meta.getDynamicWildcard();
        data.indexOfSourceWildcard = data.previousRowMeta.indexOfValue( realSourceAttachedWildcard );
        if ( data.indexOfSourceWildcard < 0 ) {
          throw new KettleException( BaseMessages.getString(
            PKG, "Mail.Exception.CouldnotSourceAttachedWildcard", realSourceAttachedWildcard ) );
        }
      }
    }
  }

  private void cacheSourceFileNameField() throws KettleException {
    if ( data.indexOfSourceFilename < 0 ) {
      String realSourceAttachedFilename = meta.getDynamicFieldname();
      data.indexOfSourceFilename = data.previousRowMeta.indexOfValue( realSourceAttachedFilename );
      if ( data.indexOfSourceFilename < 0 ) {
        throw new KettleException( BaseMessages.getString(
          PKG, "Mail.Exception.CouldnotSourceAttachedFilenameField", realSourceAttachedFilename ) );
      }
    }
  }

  public void sendMail( Object[] r, String server, int port, String senderAddress, String senderName,
    String destination, String destinationCc, String destinationBCc, String contactPerson, String contactPhone,
    String authenticationUser, String authenticationPassword, String mailSubject, String comment,
    String replyToAddresses ) throws Exception {

    // Send an e-mail...
    // create some properties and get the default Session

    String protocol = "smtp";
    if ( meta.isUsingSecureAuthentication() ) { // PDI-2955
      // if (meta.isUsingAuthentication()) {
      if ( meta.getSecureConnectionType().equals( "TLS" ) ) {
        // Allow TLS authentication

View on GitHub (pinned to f3058517a1)