Debug and Fix Statamic Email Problems

David Childs

Discover how to debug and fix common Statamic contact form email problems, including blank message fields and configuration conflicts.

Sometimes the best tutorials come from real debugging sessions. Today, I encountered a frustrating issue with my Statamic contact form: emails weren't being sent, and when they were, the message field was completely blank. Here's how I diagnosed and fixed these issues, step by step.

The Problem

My Statamic site had a contact form that looked perfect on the frontend, but behind the scenes, it was failing in two critical ways:

  1. Emails weren't being sent reliably - Some would go through, others wouldn't
  2. The message field was always blank - Even when emails were delivered, the most important field was empty

If you've faced similar issues, you know how frustrating this can be. Let's walk through the debugging process and solutions.

Discovery Phase: Understanding the Issue

The first step was understanding what was actually happening. I started by checking the Laravel logs:

tail -100 storage/logs/laravel.log | grep -E "(mail|email|message|contact)" -i

This revealed several critical errors:

[2025-08-17 13:03:49] Production.DEBUG: Cannot render an object variable as a string: {{ message }}

This error told me that the message field was being passed as an object, not a string - a common issue when Statamic's field augmentation system meets email templates.

Issue #1: Duplicate Mail Configuration

While investigating, I discovered duplicate MAIL_ settings in my .env file:

# First set of configurations
MAIL_MAILER=log
MAIL_HOST=email-smtp.us-east-1.amazonaws.com
MAIL_PORT=587
MAIL_USERNAME=your-ses-smtp-username
MAIL_PASSWORD=your-ses-smtp-password

# ... later in the file ...

# Duplicate configurations (causing conflicts!)
MAIL_MAILER=smtp
MAIL_HOST=email-smtp.us-east-1.amazonaws.com
MAIL_PORT=587
MAIL_USERNAME=ACTUAL_USERNAME_HERE
MAIL_PASSWORD=ACTUAL_PASSWORD_HERE

The Problem: Laravel was reading conflicting values, with the first MAIL_MAILER=log potentially overriding the actual SMTP configuration.

The Solution: Clean up the .env file to have only one set of mail configurations:

# Email Configuration - AWS SES SMTP
MAIL_MAILER=smtp
MAIL_HOST=email-smtp.us-east-1.amazonaws.com
MAIL_PORT=587
MAIL_USERNAME=YOUR_SES_USERNAME
MAIL_PASSWORD=YOUR_SES_PASSWORD
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="noreply@yourdomain.com"
MAIL_FROM_NAME="${APP_NAME}"
MAIL_TO_ADDRESS="contact@yourdomain.com"

Issue #2: Message Field Rendering as Object

The more complex issue was the message field showing up blank in emails. The error log showed that Statamic was passing the message as a Statamic\Fields\Value object rather than a plain string.

Understanding the Root Cause

When Statamic processes form submissions, it augments the field values, wrapping them in Value objects that provide additional functionality. This is great for templating but causes issues when email templates expect plain strings.

Initial Attempt: Custom Data in Form YAML

My first attempt was to pass custom data in the form configuration:

email:
  -
    to: '{{ config:mail.to_address }}'
    from: '{{ config:mail.from_address }}'
    subject: 'Contact Form: {{ subject }}'
    html: emails/contact
    text: emails/contact_text
    data:
      name: '{{ name }}'
      email: '{{ email }}'
      message: '{{ message }}'  # This still passed as object!

This didn't work because the data was still being augmented.

The Working Solution: Using Fields Loop

The solution was to remove the custom data and use the {{ fields }} loop in the email template, which properly handles Value objects:

# In resources/forms/contact.yaml
email:
  -
    to: '{{ config:mail.to_address }}'
    from: '{{ config:mail.from_address }}'
    reply_to: '{{ email }}'
    subject: 'Contact Form Submission: {{ subject }}'
    html: emails/contact
    text: emails/contact_text
    # No custom data field - let Statamic handle it

Then in the email template:

{{ fields }}
    {{ if value && fieldtype != 'spacer' }}
    <div class="field">
        <span class="label">{{ display }}</span>
        <div class="value">
            {{ if handle == 'email' }}
                <a href="mailto:{{ value }}">{{ value }}</a>
            {{ else }}
                {{ value }}
            {{ /if }}
        </div>
    </div>
    {{ /if }}
{{ /fields }}

Issue #3: Message Formatting and Spacing

Once the message was displaying, I noticed the formatting was off - too much padding and poor paragraph handling.

The Bard Editor Experiment

I initially tried using Statamic's Bard rich text editor:

handle: message
field:
  type: bard
  save_html: true
  buttons:
    - bold
    - italic
    - unorderedlist
    - orderedlist

While this provided rich text capabilities, it introduced complexity and spacing issues in the email templates. The HTML output was difficult to style consistently.

The Simple Solution: Textarea with nl2br

I reverted to a simple textarea with proper line break handling:

handle: message
field:
  display: Message
  type: textarea
  required: true
  validate:
    - required
    - min:10
  character_limit: 5000
  rows: 8

And in the email template:

{{ if handle == 'message' }}
    <div class="message-content">
        {{ value | nl2br | raw }}
    </div>
{{ /if }}

The nl2br filter converts line breaks to <br> tags, and raw outputs the HTML without escaping. This preserves paragraph formatting while keeping things simple.

Testing the Solution

To verify everything was working, I created a test script using Laravel's Tinker:

php artisan tinker

$form = \Statamic\Facades\Form::find('contact');
$submission = $form->makeSubmission()->data([
    'name' => 'Test User',
    'email' => 'test@example.com',
    'subject' => 'Test Subject',
    'message' => "First paragraph here.\n\nSecond paragraph here.",
    'phone' => '555-1234'
]);

$email = new \Statamic\Forms\Email(
    $submission,
    [
        'to' => config('mail.to_address'),
        'from' => config('mail.from_address'),
        'subject' => 'Test Email',
        'html' => 'emails/contact',
        'text' => 'emails/contact_text'
    ],
    \Statamic\Facades\Site::current()
);

Mail::send($email);
echo 'Test email sent successfully';

Key Takeaways

  1. Check for duplicate configurations - Always search your entire .env file for duplicates when debugging configuration issues.

  2. Understand Statamic's augmentation - Field values in Statamic are often Value objects, not plain strings. Use the {{ fields }} loop or access the value property correctly.

  3. Keep it simple - A textarea with nl2br filtering is often better than a complex rich text editor for contact forms.

  4. Test incrementally - Use Tinker to test email sending separately from form submission to isolate issues.

  5. Check the logs - Laravel's debug logs often contain the exact error message you need to understand the problem.

The Final Working Configuration

Here's what finally worked:

Form Configuration (resources/forms/contact.yaml)

title: 'Contact Form'
handle: contact
fields:
  - handle: name
    field:
      type: text
      required: true
  - handle: email
    field:
      type: text
      input_type: email
      required: true
  - handle: subject
    field:
      type: text
      required: true
  - handle: message
    field:
      type: textarea
      required: true
      rows: 8
email:
  -
    to: '{{ config:mail.to_address }}'
    from: '{{ config:mail.from_address }}'
    reply_to: '{{ email }}'
    subject: 'Contact Form: {{ subject }}'
    html: emails/contact
    text: emails/contact_text

Email Template (resources/views/emails/contact.antlers.html)

{{ fields }}
    {{ if value && fieldtype != 'spacer' }}
    <div class="field">
        <span class="label">{{ display }}</span>
        <div class="value">
            {{ if handle == 'email' }}
                <a href="mailto:{{ value }}">{{ value }}</a>
            {{ elseif handle == 'message' }}
                <div class="message-content">
                    {{ value | nl2br | raw }}
                </div>
            {{ else }}
                {{ value }}
            {{ /if }}
        </div>
    </div>
    {{ /if }}
{{ /fields }}

Conclusion

Debugging email issues in Statamic requires understanding how the system processes and augments data. The key is recognizing that Statamic's Value objects need special handling in email templates, and that simpler solutions (like textarea with nl2br) often work better than complex ones (like rich text editors).

If you're facing similar issues, start by checking your configuration for duplicates, understand how your data is being passed to templates, and don't be afraid to simplify your approach. Sometimes the best solution is the simplest one.

Remember: when debugging email issues, always check your logs, test incrementally, and understand the data types being passed between components. Happy debugging!

Share this article

DC

David Childs

Consulting Systems Engineer with over 10 years of experience building scalable infrastructure and helping organizations optimize their technology stack.

Related Articles