Testing & Troubleshooting Velocity

Dynamic Content Preview

Before sending, preview how Velocity variables render with real data directly in the message editor.

Go to Messages → Messages, open the email, and click Additional settings → Configuring dynamic content.

Enter the parameter values in JSON format and click View message:

{
  "firstName": "Jordan",
  "subscriptionPlan": "Premium",
  "price": 49.99,
  "items": [
    {
      "product": "One-month subscription",
      "renewalDate": "2026-04-03"
    }
  ]
}

If there are errors in the Velocity code, the preview will show an error description instead of the rendered message.


Testing with Event History

To test a triggered message with real event data:

  1. Go to Automation → Event history.
  2. Find the relevant event type and click on any event.
  3. Copy the parameters from the event.
  4. Paste them into the Configuring dynamic content panel.

This ensures the variable names in your template match exactly what the event sends.


Checking Available Variable Context

The variables available in a message depend on the data source:

SourceAvailable in
Contact fieldsAny message, any channel
Event parametersMessages sent through the workflow triggered by that event
External source dataMessages with the data source connected

If a variable renders as empty or as a literal string, check whether the expected data source is actually available in the current context.


Case Sensitivity Rules

Data typeCase sensitivity
Contact field namesCase-insensitive: ${firstName} = ${FIRSTNAME}
Event parameter namesCase-sensitive: $subscriptionPlan$SubscriptionPlan
External source field namesCase-sensitive: matches column headers or JSON keys exactly

The most common mistake when moving from contact fields to event params: assuming field names are case-insensitive everywhere. They are not.


Variable not Substituted

Symptom: the message contains a literal $firstName or $subscriptionPlan instead of the actual value.

Causes and fixes:

CauseFix
Variable name doesn't match the field or parameter nameCheck spelling and case against the contact field list or event parameters in Event history
Value is missing and bare $var syntax is usedUse $!{var} (silent) or ${var|'fallback'}
Event parameter is not available in this contextVerify the message is sent through the correct workflow
External data source is not connected to the messageConnect the data source in message settings

Directive Rendering Issues in Email

Symptom: #foreach or #if content renders as raw text, or the email layout breaks.

Cause: directives in email HTML must be wrapped in comments. Without the comment wrapper, the email client treats them as invalid markup.

Fix: wrap all directives in HTML comments:

<!--#foreach($item in $items)-->
  <tr>
    <td>$!item.product</td>
  </tr>
<!--#end-->

<!--#if($billingCountry == 'US')-->
  <p>Billed in USD.</p>
<!--#end-->

This rule applies only to email. In SMS, Mobile Push, Web Push, and App Inbox, directives are used without comment wrappers.


Common Mistakes with Arrays and Nested Objects

Index out of bounds

$items[2].product — error if the array has fewer than 3 elements.

Fix: use #foreach when the array size is not known in advance, or check the size first:

#if($items.size() > 2)
  $items[2].product
#end

Wrong Variable Path for Structured Data

A variable may fail if the path does not match the actual structure of the event payload, external source response, or webhook response.

Fix: check the available fields and nested structure in your test data, then update the variable path accordingly.


Missing #end

Every #if and #foreach must be closed with #end. A missing #end breaks rendering for everything after it in the template.

<!--#if($billingCountry == 'US')-->
  <p>Billed in USD.</p>
<!--#end-->

Nested Object not Resolving

  • $lastTraining.trainingDay — works if lastTraining is an object
  • $lastTraining[0].trainingDay — use this if lastTraining is an array

If a nested value is not rendering, check whether the parent is an object or an array in the event payload.


Next Steps

  • Velocity Reference — full syntax reference
  • Using Velocity in Messages — practical examples for message templates
  • Using Velocity in Workflows — practical examples for workflow expressions