pentaho/pentaho-kettle · error · KettleException

Mail.Exception.CouldnotFindCommentField

Error message

Mail.Exception.CouldnotFindCommentField

What it means

The Mail step is configured to take the mail comment from a field, but the configured comment field name was not found in the incoming row. The indexOfValue lookup in cacheFieldsPosition returned -1, so this KettleException is thrown before processing.

Solutions

  1. Confirm the 'Comment' setting contains the exact name of a field present in the input stream.
  2. Preview upstream rows and fix any rename/mismatch.
  3. If a constant comment is needed, remove the field reference and set the comment statically.

Example fix

// before
// Comment field: "See attached invoice" (literal text)
// after
// Upstream step creates field "mail_comment" = 'See attached invoice';
// Comment field set to "mail_comment"
Defensive patterns

Strategy: validation

Validate before calling

if (meta.getComment() != null && !meta.getComment().isEmpty()
    && rowMeta.indexOfValue(meta.getComment()) < 0) {
  throw new KettleException("Comment field not found in input stream: " + meta.getComment());
}

Try / catch

try { sendMail(); } catch (KettleException e) { if (e.getMessage().contains("CouldnotFindCommentField")) { logError("Comment setting must reference an existing stream field"); } throw e; }

Prevention

When it happens

Trigger: meta.getComment() is non-empty and data.previousRowMeta.indexOfValue(realComment) < 0, i.e. no field in the input row matches the configured comment field name.

Common situations: Literal comment text entered into a field-name setting; upstream field renamed/removed; copy-pasted step from a transformation with a different row layout.

Related errors


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

Appendix: source

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

    if ( !Utils.isEmpty( meta.getSubject() ) ) {
      // cache the position of the subject field
      if ( data.indexOfSubject < 0 ) {
        String realSubject = meta.getSubject();
        data.indexOfSubject = data.previousRowMeta.indexOfValue( realSubject );
        if ( data.indexOfSubject < 0 ) {
          throw new KettleException( BaseMessages.getString(
            PKG, "Mail.Exception.CouldnotFindSubjectField", realSubject ) );
        }
      }
    }
    // Mail Comment
    if ( !Utils.isEmpty( meta.getComment() ) ) {
      // cache the position of the comment field
      if ( data.indexOfComment < 0 ) {
        String realComment = meta.getComment();
        data.indexOfComment = data.previousRowMeta.indexOfValue( realComment );
        if ( data.indexOfComment < 0 ) {
          throw new KettleException( BaseMessages.getString(
            PKG, "Mail.Exception.CouldnotFindCommentField", realComment ) );
        }
      }
    }

    if ( meta.isAttachContentFromField() ) {
      // We are dealing with file content directly loaded from file
      // and not physical file
      String attachedContentField = meta.getAttachContentField();
      if ( Utils.isEmpty( attachedContentField ) ) {
        // Empty Field
        throw new KettleException( BaseMessages.getString( PKG, "Mail.Exception.AttachedContentFieldEmpty" ) );
      }
      data.indexOfAttachedContent = data.previousRowMeta.indexOfValue( attachedContentField );
      if ( data.indexOfAttachedContent < 0 ) {
        throw new KettleException( BaseMessages.getString(
          PKG, "Mail.Exception.CouldnotFindAttachedContentField", attachedContentField ) );
      }

View on GitHub (pinned to f3058517a1)