Skip to Content
πŸŽ‰ Scout Docs 2.0 is here!
WorkflowsLogic and State

Logic and State

Workflows pass data from block to block through a shared state object. Clean state design keeps your workflows predictable, testable and easy to debug.

How State Moves

Each block can read from earlier blocks using template references:

  • {{inputs.field_name}} β€” reads from the workflow’s Input block
  • {{block_id.output}} β€” reads a prior block’s output by its block ID
  • {{block_id.some_field}} β€” reads a specific field from a prior block’s output

Here’s what that looks like in practice. Say you have three blocks β€” an Input block, an enrich_user block and a send_email block:

{# In the enrich_user block β€” read from workflow inputs #} User name: {{ inputs.user_name }} Account tier: {{ inputs.account_tier }} {# In the send_email block β€” read from the enrich_user block #} Full name: {{ enrich_user.full_name }} Plan label: {{ enrich_user.plan_label }}

Use explicit mappings so each block receives only what it needs. Passing the entire state object into every block makes debugging harder and output less predictable.

Conditional Logic

Use Jinja if/else blocks to branch on state values. This is how you handle different cases without adding separate blocks for each path.

{# Route by account tier #} {% if inputs.account_tier == "enterprise" %} Priority support queue β€” SLA: 4 hours {% elif inputs.account_tier == "pro" %} Standard support queue β€” SLA: 24 hours {% else %} Community support β€” check our docs first {% endif %}

You can also use conditionals to build dynamic prompts:

You are a support assistant. {% if inputs.has_prior_conversation %} The user has contacted us before. Be warm and reference their history. {% else %} This is a new user. Introduce yourself briefly. {% endif %} User message: {{ inputs.message }}

For more on template syntax, see Jinja Templates.

Global Variables

Scout provides built-in date and time variables you can use in any template without configuration:

VariableExample output
{{__exp_global.current_date}}2025-06-15
{{__exp_global.current_time}}14:23:01
{{__exp_global.current_datetime}}2025-06-15 14:23:01
{{__exp_global.current_time_utc}}21:23:01 UTC
{{__exp_global.current_time_pacific}}14:23:01 PDT

Use these for timestamps, logging and user-facing messages that need to reflect the current time:

{# Add a timestamp to a log entry #} [{{ __exp_global.current_datetime }}] User {{ inputs.user_id }} submitted request {# Add a date to a generated document #} Report generated on {{ __exp_global.current_date }}

State Design Tips

A few habits that make workflows easier to maintain:

  • Keep payloads small. Only pass the fields a block actually needs, not the whole prior block output.
  • Use stable key names. Renaming a field breaks every downstream reference silently.
  • Normalize once. Clean and format data in one early block, then reuse those normalized fields downstream.
  • Prefer structured output over string building. Return {"user_id": "abc", "status": "active"} rather than "user abc is active" β€” structured data is easier to branch on.

Error and Fallback Paths

Don’t assume the happy path. Add branch logic for expected failures so downstream blocks can respond correctly instead of breaking.

Common cases to handle:

  • Missing or empty input fields
  • Empty search or lookup results
  • External API failures or timeouts

Return explicit status fields from each block so downstream blocks can branch:

{ "ok": true, "data": { "user_id": "abc", "email": "user@example.com" } }
{ "ok": false, "error_code": "USER_NOT_FOUND", "message": "No user found for that ID" }

Then branch in the next block based on ok:

{% if lookup_user.ok %} Found {{ lookup_user.data.email }} β€” continuing workflow {% else %} Stopping: {{ lookup_user.error_code }} β€” {{ lookup_user.message }} {% endif %}

This pattern keeps error handling explicit and auditable rather than buried in block logic.

Next Steps

  • Blocks: Choose the right block types for your workflow
  • Jinja Templates: Build dynamic expressions safely
  • History: Track and restore changes

Built with ❀️ by Scout OS

Last updated on