All nodes/Data/Values & State

Template

Builds text from a template with values substituted from other nodes: {{nodes.llm_1.output}}, {{inputs.message}}. Used to compose prompts, messages, and strings from dynamic data.

Template
InputResult
Var

Type in the graph: template

Exec

An error branch can be enabled (expose_error_output) to handle failures on their own path.

Ports can be split into separate execution and data handles.

Try it

Minimal working workflow

Entry
Template
Exit
  • Execute + Data
Press “Copy nodes”, open the editor and hit Ctrl+V on the canvas.

Runs as pasted

When to use it

Template is the node for anything whose output has to be text: a prompt for a model, a reply to the user, a request body, a key to store something under. It assembles one string from values that live in different nodes and variables.

You do not always need a separate node: many text fields on other nodes (a prompt, a message body) understand the same substitution syntax. Reach for Template when the assembled text is consumed by several nodes, when the assembly is a step in its own right that you want to see in the run log, or when the text must be built before it reaches a node that has no templatable field.

How it works

The same namespaces are available as in any other templatable field:

  • {{ inputs.input }} — the value that arrived at the Input port. This is also the default template: a freshly dropped node simply passes the value through.
  • {{ nodes.<id>.output }} — the result of any node that already ran, addressed by its id.
  • {{ variables.<name> }} — session variables declared by Variable nodes.
  • {{ var }} — the value of the Var node wired into the Var port; this is also how thread-scoped variables are read.
  • {{ loop.* }} — the current iteration’s data when the node sits inside a loop.

Jinja conditions and loops ({% if %}, {% for %}) work, as do filters such as | default("—") or | join(", "). The node has no execution input: it is either triggered through the Input port, or its value is pulled by a consumer over a data edge.

Common mistakes

  • An empty template is rejected. It would return an empty string and throw the incoming value away, so the run stops with a message saying the template text is required. If you want the node to pass things through, leave {{ inputs.input }} in place.
  • nodes.<id> is the node id, not its label. A reference to an id that does not exist renders as nothing; the validator warns about it and suggests the closest real id.
  • The result is always a string. Even when the expression evaluated to a number or an object, what travels downstream is text. If the consumer needs an object, route the value around the template or parse it further with another node.
  • {{ variables.X }} only sees session variables. Read a thread-scoped one through the Var port ({{ var }}) or through {{ nodes.<id>.output }} of the Var node.

Inputs

PortWirePayloadNotes
InputinputExecute + Dataexecute_data

Run trigger and context for {{inputs.input}} in the template

VarvarDatadata

Optional: connect a Var node for {{var}} in the template

Outputs

PortWirePayloadNotes
ResultoutputExecute + Dataexecute_dataobject

Configuration

FieldTypeDefaultDescription
Templatetemplatestring{{ inputs.input }}

Use {{var}}, {{nodes.id.output}}, {{inputs.handle}}. Connect a Var node to the Var handle for stateful context. An empty template returns an empty string and drops the incoming value.

supports templates

Shared fields

Every node has these three — the platform adds them, not the node author.

  • expose_error_output — When enabled, show an execution output to connect nodes that run if this step fails.
  • split_ports_in — Show separate execution and data input handles instead of one combined port.
  • split_ports_out — Show separate execution and data output handles instead of one combined port.

Ready-made examples using this node