Errors and limits
What the contact sees
If an expression can't be calculated — for example, a variable holds text instead of a number or there's no such function — the contact sees an empty spot there. If there's a typo (an unclosed parenthesis), the insertion stays in the text as written. Either way, the reason shows up in the bot preview and in the block log, and the rest of the message is sent as usual.
The bot treats text as an expression when it contains a variable with $ or a function call, such as round(. If it has neither — say, {{#each items}} — the bot leaves the text as written and doesn't count it as an error. This way texts that use curly braces for something else don't break.
Where to find the reason
- Block editor. As you type, the parts of a placeholder are colour-coded, and one that will not work is underlined in red with the reason shown below the field.
- Bot preview. Click "Test the bot" in the builder and go through the scenario. If an insertion fails, a yellow box appears below the chat: the block name (a link to it on the canvas), the insertion itself and the reason.
- Block log. For blocks that keep a log (HTTP request and others), template errors are written to the run log, in the "Template errors" section.
Common mistakes
| What was written | What's wrong | How to fix it |
|---|---|---|
A variable name with spaces written with $ |
After $ the bot reads the name only up to the space |
{{ var("Client name") }}, see names with spaces |
A global variable written without global in an expression |
In expressions, global variables are read only through the function | {{ global("Rate (USD)") * 2 }} |
{{ round($price * 0.9 }} |
The parenthesis isn't closed | {{ round($price * 0.9) }} |
{{ discount($price, 10) }} |
There's no such function | Check the name in the function reference |
{{ $city * 2 }} |
The variable holds text, not a number | Make sure the variable holds a number |
{{ phone + 1 }} with no phone number |
Empty value | Add a fallback: {{ (phone ?? 0) + 1 }} |
{{ upper(getInviteLink()) }} in a button |
Buttons allow only simple functions | Move the link to the message text |
{{ $a > 1 ? messageToTelegram("...") : "" }} |
Functions that send messages or write variables can't go inside an expression | Use the function as a separate insertion |
Limits
| What | Limit |
|---|---|
Expression length inside {{ ... }} |
1000 characters. Longer text stays as written |
| Result of one insertion | 10,000 characters on top of the length of the variables read. A variable value is output in full at any length, including via var(), with trim, upper, len over it and with added text: {{ $x ~ "!" }} |
| Expressions in one text | 200 |
| Functions in one text | 100 simple and 10 others. Beyond the limit, functions are not run: a standalone insertion like {{ getInviteLink() }} stays in the text as written, and inside an expression the function gives an empty spot and an error in the log. Reading a variable ($name, var(), global()) doesn't count as a function |
Expressions don't support regular expressions (matches), ranges (1..10) or access to the platform's internal data.