pentaho/pentaho-kettle · error · KettleException

Mail.Exception.CouldnotSourceAttachedWildcard

Error message

Mail.Exception.CouldnotSourceAttachedWildcard

What it means

Thrown by Mail.cacheWildCardField when a dynamic wildcard field name is configured (meta.getDynamicWildcard()) but that field cannot be found in the incoming row: data.previousRowMeta.indexOfValue(name) returns -1. Unlike the empty-field checks, the name is present in config but does not match any column of the row arriving at the step, typically due to a typo, renamed field, or an upstream step that no longer produces the column.

Solutions

  1. Verify the exact field name in the Mail step's wildcard-field setting matches an incoming column (case-sensitive).
  2. Add the column upstream (e.g. via Select Values or a User Defined Java Expression) so the wildcard reaches the Mail step.
  3. Re-open and re-save the Mail step after upstream changes so field indices refresh.
  4. Log data.previousRowMeta.getFieldNames() before the step to inspect actual available columns.

Example fix

// upstream: ensure the column exists before the Mail step
// before
String field = data.previousRowMeta.indexOfValue("wildcard") >= 0 ? "wildcard" : data.previousRowMeta.getFieldNames()[0];
// after — fix the configuration to a real column name
// Mail step dialog: wildcard field = "fileWildcard" (exists in row) instead of "wildcard"
String configured = meta.getDynamicWildcard(); // "fileWildcard"
int idx = data.previousRowMeta.indexOfValue(configured); // >= 0
Defensive patterns

Strategy: validation

Validate before calling

// Before the Mail step, verify the wildcard field exists in the row
int idx = rowMeta.indexOfValue( configuredWildcardField );
if ( idx < 0 ) {
  throw new IllegalArgumentException("Wildcard field '" + configuredWildcardField + "' not in row: "
    + Arrays.toString( rowMeta.getFieldNames() ) );
}

Try / catch

try { transformation.execute(); } catch ( KettleException e ) { if ( e.getMessage().contains("CouldnotSourceAttachedWildcard") ) { /* compare configured name to rowMeta field names and fix reference */ } else { throw e; } }

Prevention

When it happens

Trigger: The wildcard field selected in the Mail step does not exist in the rowset at execution time; an upstream step (e.g. a filter or select-values) renamed/dropped the column; case mismatch between configured name and actual field name; processAttachedFiles runs before the first row populates previousRowMeta correctly.

Common situations: Refactoring upstream transformations without updating the Mail step's field references; locale/case discrepancies between environments; dynamic wildcard option enabled while the hop delivers rows without that 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/f10e3a0224b8a6a8. Report an issue: GitHub.

Appendix: source

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

    if ( meta.isDynamicFilename() ) {
      // cache the position of the attached source filename field
      cacheSourceFileNameField();
      // cache the position of the attached wildcard field
      cacheWildCardField();
    } else {
      // static attached filenames
      data.realSourceFileFoldername = environmentSubstitute( meta.getSourceFileFoldername() );
      data.realSourceWildcard = environmentSubstitute( meta.getSourceWildcard() );
    }
  }

  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,

View on GitHub (pinned to f3058517a1)