Variable
Sets, computes, converts, resets, or removes flow variables.
Each row says what you want to do to one variable: add to a counter, append what OCR read, convert text to a number, copy a value, reset it. You choose the operation; the node writes the expression for you.
A variable is created automatically the first time a row sets it.
Purpose
Give a flow memory that lasts for the run — counters, flags, copied values, converted OCR reads.
When to use it
- Counting iterations, attempts, or items processed.
- Converting an OCR string into a number you can compare.
- Copying a value so it survives past the node that produced it.
- Setting a flag that a later If branches on.
- Printing a value into the run log while debugging.
When not to use it
- To remember something across runs — use a per-instance variable (below) or Runtime Memory.
- To pass an argument into another flow — use a Sub Flow input mapping.
How it runs
Two properties define this node:
It is all-or-nothing. If any row faults, no row is applied. You never get a half-updated set of variables.
Rows do not see each other. Every row is evaluated before any is stored, so a second row reads the value from before this node — not the one the first row just wrote.
Row 1: count = {{count}} + 1
Row 2: total = {{count}} ← reads the OLD count
If one assignment must observe another, use two Variable nodes.
Settings
| Setting | Type | Notes |
|---|---|---|
| Operation | choice | Grouped as Store a value / Numbers / Text / Convert / Manage |
| Target | variable path | Which variable this row writes |
| Value / expression | string | ≤ 1000 chars |
| Store as | choice | Auto, Text, or Yes/No |
| If not a number, use | value | Fallback for numeric operations |
| Ignore surrounding text | boolean | Convert-to-number: take the first number found |
| Store per instance | boolean | Write to the Instance scope instead of the run |
| Expire after | integer | 1 s – 1 year; the value reverts to its default |
Rows are limited to a practical list per node; each row targets exactly one variable.
The operations
| Group | Operation | Effect |
|---|---|---|
| Store | Set to | Store a value or expression |
| Numbers | Add / Subtract | Treats an unset variable as 0 |
| Numbers | Multiply / Divide | Treats an unset variable as 1 |
| Text | Append | Concatenate text |
| Convert | Convert to number | Parse text into a number, with a fallback |
| Manage | Reset | Return the variable to its default, keeping it |
| Manage | Remove | Delete the variable for the rest of the run |
| Manage | Show in run log | Print the value without changing it |
Reset is not Remove. Reset restores the declared default and keeps the variable; Remove deletes it.
Store as
Auto keeps whatever the value already is — a number stays a number, a variable keeps its own type, anything else becomes text. Force a type with Text or Yes/No.
For a number read off the screen, use Convert to number, which adds a fallback.
Convert to number, and why you need it
A screen read is text, even when it looks like a number. "LEVEL 5" is a string; so is "1167".
Convert to number parses it, and Ignore surrounding text takes the first number found — so "LEVEL 5" becomes 5.
The If not a number, use field supplies a fallback when parsing fails. Clearing it makes that case route Failure instead, which you can branch on.
Store per instance
Writes to the Instance scope: the value survives runs and restarts, is visible to every flow on that instance, and is isolated between instances. See Variables and Memory.
Expire after
The value returns to the variable's default once the time is up (maximum one year). Off means permanent.
Ports
| Port | Taken when | Required |
|---|---|---|
| Success | All rows applied (output: the count assigned) | Yes |
| Failure | A row's value could not be worked out, or its type did not match the variable | No |
| Fatal | Configuration fault | No — never followed |
Basic example
A retry counter:
- Operation: Add to it
- Target:
attempts - Value:
1
Starting from 0 automatically on the first run.
Realistic example — count and decide
The two-node idiom that replaces most loop counters:
Reset items_done to 0 at the natural boundary — when a trip genuinely ends — not at the top of the loop, or it never reaches its limit.
Advanced example — make an OCR read usable
Without the conversion, {{level}} >= 5 compares a string and quietly does the wrong thing.
Best practices
- Use one Variable node per logical step. Rows within a node are simultaneous.
- Give counters a default of
0.null + 1is not a number. - Always set a fallback on conversions, unless you want Failure as a branch.
- Use Show in run log while debugging, then remove it.
- Reset at the real boundary, not at loop top.
- Name variables after meaning —
items_done, noti. - Wire Failure on nodes doing conversions.
Performance notes
- Pure computation — no device interaction. Effectively free.
- The all-or-nothing check evaluates every row before storing, so a node with many rows does one validation pass then one write pass. This is still trivial compared with any detection node.
- Per-instance writes hit persistent storage. Avoid putting them inside a tight loop.
Memory notes
- Flow variables live in the run's execution context and are released when the run finalizes.
- Per-instance variables persist on disk indefinitely — give them a deliberate reset path.
- Remove frees a variable for the rest of the run; Reset keeps it allocated at its default.
Common mistakes
| Mistake | What happens | Fix |
|---|---|---|
| Doing maths on OCR text | Silently wrong or Failure | Convert to number first |
| Expecting row 2 to see row 1 | It reads the pre-node value | Use two Variable nodes |
| Expecting Reset to delete | Reset restores the default | Use Remove |
| Counter with no default | Arithmetic produces nothing | Default to 0 |
| Resetting a counter at loop top | Never reaches its limit | Reset at the trip boundary |
| Changing a variable's type mid-run | Row routes Failure | Keep one type per variable |
Troubleshooting
No variables changed and the node routed Failure. All-or-nothing: one bad row blocked every row. Check each row's value and type.
My counter is always 1.
The row is setting rather than adding. Use Add to it, or {{count}} + 1.
A conversion keeps failing. The text has no parseable number. Turn on Ignore surrounding text, or set a fallback.
A per-instance value is stale from days ago. That is what per-instance means. Clear it explicitly in a setup flow.
FAQ
Do I have to declare a variable first? A row that sets one creates it. Declaring it gives you a type and a default, which is better practice.
What happens on Add to an unset variable?
Add/Subtract treat it as 0; Multiply/Divide treat it as 1.
Is {{name}} different from ${name}?
No.
What is the maximum expire-after? One year.
Related nodes
- If — branch on what you stored
- Read Text — the usual source of values
- Runtime Memory — cross-run memory with TTL
- Sub Flow — passing values into another flow
Related pages
- Variables and Memory — scopes and types in full