pentaho/pentaho-kettle · error · KettleException
Mail.Exception.CouldnotFindAttachedContentFileNameField
Error message
Mail.Exception.CouldnotFindAttachedContentFileNameField
What it means
'Attach content from field' is enabled and both required field names were set, but the attached-content filename field does not exist in the incoming row. The indexOfValue lookup in cacheFieldsPosition returned -1 and this KettleException is thrown.
Solutions
- Check the attachment filename field name in the Mail step against the actual input stream fields (exact, case-sensitive match).
- Preview the upstream hop to verify the filename field is produced.
- Disable 'Attach content from field' to attach physical files instead.
Example fix
// before
// attachContentFileNameField = "filename" but stream field is "report_name"
// after
// meta.setAttachContentFileNameField("report_name"); Defensive patterns
Strategy: validation
Validate before calling
if (meta.isAttachContentFromField()
&& meta.getAttachContentFileNameField() != null && !meta.getAttachContentFileNameField().isEmpty()
&& rowMeta.indexOfValue(meta.getAttachContentFileNameField()) < 0) {
throw new KettleException("Attached content filename field not found: " + meta.getAttachContentFileNameField());
} Try / catch
try { sendMail(); } catch (KettleException e) { if (e.getMessage().contains("CouldnotFindAttachedContentFileNameField")) { logError("Attachment filename field not present in the input stream"); } throw e; } Prevention
- Ensure an upstream step produces the attachment filename column.
- Preview rows after schema changes to catch renamed fields early.
- Use the dialog's field dropdown so names always match the stream exactly.
When it happens
Trigger: meta.isAttachContentFromField() is true, attachedContentFileNameField is non-empty, and data.previousRowMeta.indexOfValue(attachedContentFileNameField) < 0.
Common situations: Filename field name typo; upstream step renamed the filename column; step copied between transformations with different schemas.
Related errors
- Mail.Exception.AttachedContentFieldEmpty
- Mail.Exception.AttachedContentFileNameFieldEmpty
- Mail.Exception.CouldnotFindAttachedContentField
- Mail.Exception.CouldnotSourceAttachedZipFilenameField
- Mail.Exception.CouldnotFindAuthenticationPassField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/b5b66b13c8542f83.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/mail/impl/src/main/java/org/pentaho/di/trans/steps/mail/Mail.java:429
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 ) );
}
// Attached content filename
String attachedContentFileNameField = meta.getAttachContentFileNameField();
if ( Utils.isEmpty( attachedContentFileNameField ) ) {
// Empty Field
throw new KettleException( BaseMessages.getString(
PKG, "Mail.Exception.AttachedContentFileNameFieldEmpty" ) );
}
data.IndexOfAttachedFilename = data.previousRowMeta.indexOfValue( attachedContentFileNameField );
if ( data.IndexOfAttachedFilename < 0 ) {
throw new KettleException( BaseMessages.getString(
PKG, "Mail.Exception.CouldnotFindAttachedContentFileNameField", attachedContentFileNameField ) );
}
} else {
// Dynamic Zipfilename
if ( meta.isZipFilenameDynamic() ) {
// cache the position of the attached source filename field
if ( data.indexOfDynamicZipFilename < 0 ) {
String realZipFilename = meta.getDynamicZipFilenameField();
data.indexOfDynamicZipFilename = data.previousRowMeta.indexOfValue( realZipFilename );
if ( data.indexOfDynamicZipFilename < 0 ) {
throw new KettleException( BaseMessages.getString(
PKG, "Mail.Exception.CouldnotSourceAttachedZipFilenameField", realZipFilename ) );
}
}
}
data.zipFileLimit = Const.toLong( environmentSubstitute( meta.getZipLimitSize() ), 0 );
if ( data.zipFileLimit > 0 ) {View on GitHub (pinned to f3058517a1)