Skip to main content

Overview

Jinba Flow supports powerful templating capabilities that allow you to:
  • Reference results from previous steps
  • Access configured secrets securely
  • Use Nunjucks templates for complex logic
  • Create dynamic, reusable workflows

Variable Placeholders

Basic Syntax

Variables are enclosed in double curly braces: {{ variable }}

Available Variables

item, itemIndex and itemCount exist only in the inputs of a step that has forEach.

Accessing Step Results

A plain {{steps.<step_id>.result...}} placeholder is inserted as text:
  • Objects and arrays become JSON
  • Strings are inserted as-is, without quotes
  • null or a missing value becomes an empty string
This automatic conversion applies only to steps.<step_id>.result... placeholders with no filter. Other objects, such as {{item}} when the item is an object, render as [object Object]; write {{item | json}} instead. A step that reads another step’s result must list that step in needs, or it may run before the result exists. See Step Module Options.
PYTHON_SANDBOX_RUN returns its output under result.data, so a later step reads it as {{steps.<step_id>.result.data}}.

Using Secrets

Secrets are configured at the workspace level and accessed securely:
Security Notes:
  • Secrets are encrypted at rest
  • Never hardcode sensitive values in workflows
  • Use secrets for API keys, tokens, and credentials

Nunjucks Templates

Jinba Flow renders templates with Nunjucks, whose syntax is close to Jinja2 but not identical. Templates are processed before step execution.

Control Structures

For Loops

Conditional Statements

Loop with Index

loop.index counts from 1 and loop.index0 counts from 0.

Built-in Functions

Nunjucks has no zip(). To walk two lists side by side, loop over one and index the other with loop.index0:

Filters

Apply transformations to values:
default replaces only a missing value. To also replace null, an empty string or false, write default('fallback_value', true). json is added by Jinba Flow and outputs strict JSON: strings keep their quotes and null stays null. There is no tojson filter. Jinba Flow also adds filters for the output of a forEach step:

Whitespace Control

Use {%- and -%} to control whitespace:
  • {%- removes whitespace before the tag
  • -%} removes whitespace after the tag

Common Patterns

The Python examples below read earlier results with json.loads(r'''{{steps.<step_id>.result}}'''). Pasting a result straight into Python code breaks on JSON values such as null, true and false. PYTHON_SANDBOX_RUN uses the value of the last line as its result; set data_type to OBJECT and end with json.dumps(...) to return structured data.

Processing Lists

Conditional Data Selection

Combining Multiple Sources

zip here is Python’s, which runs inside the sandbox. In a template, use the loop.index0 pattern shown under Built-in Functions.

Filtering Lists

Nunjucks does not support Jinja2’s {% for x in list if condition %}: it checks the condition once for the whole list, so the loop usually outputs nothing. Put the condition inside the loop instead:

Building Dynamic Prompts

Best Practices

Variable References

  • Use descriptive step IDs for clarity
  • Access only the properties you need
  • Handle potential null/undefined values with defaults

Templates

  • Keep templates readable with proper indentation
  • Use whitespace control for clean output
  • Break complex logic into multiple steps

Secrets

  • Never log or expose secret values
  • Use workspace-level secrets for team sharing
  • Rotate secrets regularly

Performance

  • Avoid deeply nested templates
  • Limit loop iterations
  • Pre-process data when possible

Troubleshooting

Common Issues

Variable not found or empty
  • Check step ID spelling
  • Make sure the referenced step is listed in needs
  • Verify the property path is correct (for PYTHON_SANDBOX_RUN, the output is under result.data)
Template syntax error
  • Check for balanced braces {{ }}
  • Verify Nunjucks tag syntax {% %}
  • Look for missing quotes in strings
Unexpected output
  • Use debug steps to inspect intermediate values
  • Check whitespace handling
  • Verify data types (string vs object)
  • [object Object] means an object was inserted without conversion; add | json
TemplateSecurityError: ... is not allowed in templates
  • Templates are flow-authored, so the engine refuses anything that could run code or read files, and the step fails instead of rendering
  • Not allowed: reading constructor, prototype or __proto__ on any value (including a result field with that name); {% asyncEach %} / {% asyncAll %}; names that are not plain identifiers (letters, digits, _, $) as a variable, loop variable, macro, filter or test
  • {% include %}, {% import %} and {% extends %} fail separately with a “template not found” render error, because no template files are loadable from a flow
  • Ordinary member access, method calls on values such as {{ steps.x.result.trim() }}, filters, range and macros keep working
  • Front-end code with its own {{ }} interpolation (for example {{ user?.name }} in an HTML snippet) must be wrapped in {% raw %} ... {% endraw %}