Variable placeholders — the silent-fail caveat
Variables in automation nodes use {{...}} syntax. Today there’s no validation that a variable path actually exists in the trigger’s data shape — a typo renders as empty in the output, with no error and no warning.
This is the single most common source of “the email went out but the name was blank” debugging sessions.
How variable paths work
Section titled “How variable paths work”A variable path is a dotted reference to data from upstream nodes:
{{<triggerNodeId>.tableEntry.data.firstName}}That reads tableEntry.data.firstName from the trigger node’s output. If the field exists, the value is substituted at run time. If it doesn’t exist, the substitution renders empty — no error.
Naming the lead, and reaching them
Section titled “Naming the lead, and reaching them”Who a lead is lives on the contacts attached to it, and the automation editor offers them as their own variable groups — Kontakt Variablen, Teilnehmer Variablen and Gebuchte Personen. They render empty when the request has nobody on it, like any other placeholder.
| Variable | Renders |
|---|---|
$contact.displayName | The primary contact’s full name |
$contact.firstName | First name. Falls back to the whole name where it was never split |
$contact.middleName | Middle name |
$contact.lastName | Last name |
$contact.email | The contact’s primary email address |
$contact.phone | The contact’s primary phone number |
$contact.isSubject | true when the lead is about the contact themselves, false when they enquire for somebody else |
$subjects.firstNames | First names of everyone the lead is about, e.g. “Anni und Billie” |
$subjects.names | Their full names, e.g. “Anni Muster und Billie Muster” |
$subjects.count | How many there are |
$attendees.firstNames | First names of the people booked into this appointment |
$attendees.names | Their full names |
$attendees.count | How many are booked |
$contactis who the message goes to.$subjectsis who the lead is about. On a parent’s enquiry for two children those differ, which is what lets one template greet the parent and name the children. On an adult enquiring for themselves,$subjectsis that adult.$attendeesonly fills on the appointment triggers (booked, starts, ends) and names only people whose booking is still live. When two siblings are booked together and one cancels, a reminder names only the one still coming. Use it in confirmation and reminder emails; use$subjectseverywhere else.$contactand$subjectsare captured when the run is triggered.$attendeesis re-read before every step.
Older flows may use $participants.*, $bookedParticipants.* or $contact.isParticipant. They
keep working, but the picker no longer offers them — new flows should use the names above.
Pool fields — the course asked about, a note, an enum — are still read the old way, through
tableEntry.data.<key> and tableEntry.customFieldData.<uuid>.
The “alte Kontakt-Variablen” warning
Section titled “The “alte Kontakt-Variablen” warning”The automations list flags flows that still read names, email or phone from lead fields with a
“N × alte Kontakt-Variablen” badge. Hover it to see which placeholders are affected, then
replace each with the matching $contact or $subjects variable and republish.
How to verify a path is valid
Section titled “How to verify a path is valid”Two techniques:
1. Hover the variable chip
Section titled “1. Hover the variable chip”In the node editor, every inserted variable renders as a colored chip. Hover over it: the editor shows the full path and resolves a sample value from the most recent trigger event (or a placeholder if no event has fired yet).
A chip that resolves to grey/blank on hover is a chip whose path doesn’t match any real field. That’s your typo.
2. Send a test trigger
Section titled “2. Send a test trigger”For each new flow:
- Publish the flow.
- Create a real test lead with all the fields you expect populated.
- Trigger the flow (e.g. by booking a test appointment).
- Inspect the resulting email / SMS / HTTP request payload.
- Anything blank that shouldn’t be blank is a path that needs fixing.
This is the only fully reliable verification today.
Where typos creep in
Section titled “Where typos creep in”The most common typo sources:
- Custom Fields:
tableEntry.data.kursinstead oftableEntry.customFieldData.<uuid>. The variable picker inserts the correct path; if you type it by hand, you’ll get it wrong. - Identity read from
data:tableEntry.data.firstNameor an email/phone Custom Field. The path is syntactically valid, but the value is empty or stale — use$contact.firstName,$contact.email,$contact.phone. - Renamed pool fields: a flow imported from a template references
course, but the pool actually exposeskurs. The path is syntactically valid, semantically wrong — silent fail. - Stale references: a Custom Field deletion + recreation gives the new field a different UUID. The flow’s reference still uses the old UUID — silent fail.
- Trigger-source mismatch: the Customer source picker is set to the wrong pool, so the available paths don’t match the actual lead’s pool.
What proper validation would look like
Section titled “What proper validation would look like”A future change will introduce plausibility-check warnings:
- Yellow warning when a node references a path that doesn’t exist in the trigger’s documented output schema.
- Red error when a node references a path that’s actively wrong (e.g. a deleted custom field UUID).
- Optional strict mode — refuse to publish a flow with any path warnings.
Until that ships, hover-verify and test-trigger every flow before publishing.
Custom Field UUID gotcha
Section titled “Custom Field UUID gotcha”The customFieldData.<uuid> path uses the UUID of the Custom Field, not the field’s name. The UUID is invisible in the editor; the variable picker inserts it correctly. You’ll see something like:
{{<triggerNodeId>.tableEntry.customFieldData.f3a8c2b1-...-...}}Don’t try to “clean up” that UUID into something readable — the engine looks up the field by UUID at run time. Replacing it with a name silently breaks the variable.
See Custom Field variables for the full path conventions.
What’s next
Section titled “What’s next”- Custom Field variables —
customFieldData.<uuid>vs.data.<key>. - Default templates — these templates have placeholder variables you have to replace before publishing.