> ## Documentation Index
> Fetch the complete documentation index at: https://docs.voxworks.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Code Step

> Run small, allow-listed Python snippets for routing and variable updates.

## What is a Code Step?

The Code Step is a flow tool that runs small, allow-listed Python snippets to validate data, update variables, and route the conversation. It runs on a normal [tool step](/flows/steps-tool).

Use it for the precise, deterministic work that an LLM shouldn't guess at — format checks, counters, flag logic, and parsing structured data returned by a [webhook](/tools/webhook).

***

## The `run()` Contract

Every Code Step must define exactly one top-level function named `run`:

```python theme={null}
def run():
    return True
```

The function:

* Must be named `run` and take no arguments
* Must return a `bool`, `list[bool]`, or `tuple[bool, ...]`
* Must not use decorators, nested functions, or classes
* Must not use imports, `global`, or `nonlocal`
* Must only call [allow-listed functions](/tools/code-step/functions)

Invalid return values (a string, a number, a non-boolean list) **fail closed**.

```python theme={null}
def run():
    return "true"   # invalid

def run():
    return 1        # invalid
```

> Do not indent `def run():` — it must start at the first column.

***

## Variables and Inputs

Read and write configured variables with double-brace `{{...}}` placeholders, and pass extra values in as mapped inputs.

```python theme={null}
def run():
    email = {{contact.email}}
    {{contact.email_verified}} = bool(email and "@" in email)
    return {{contact.email_verified}}
```

See [Variables & Inputs](/tools/code-step/variables-and-inputs) for reads, writes, the `custom` namespace, and `input_1`-style mapped inputs.

***

## Compile and Run

The Code Step is validated twice — once at startup, and again before each execution:

1. Placeholders are rendered into executable Python
2. The code is parsed and checked against the deny-by-default validator
3. `run()` executes and its return value is normalized into ordered boolean outputs

Startup compile success is logged internally, not written as a user-facing note. Compile errors, run errors, run success, and any `print(...)` output are written to the call's system notes, including the line number on failure. For example:

```text theme={null}
Tool | Code Step | Print: email present: True
Tool | Code Step | Run success: outputs={'0': True, '1': False}
Tool | Code Step | Run error on line 2: name 'input_1' is not defined | return bool(input_1)
```

> Use `print(...)` for debugging: unquoted placeholders like `print({{contact.email}})` print the resolved value, while `print("{{contact.email}}")` prints the literal placeholder text.

***

## Next Steps

* [Allowed Functions](/tools/code-step/functions) — The full deny-by-default allow-list
* [Examples](/tools/code-step/examples) — Common patterns and troubleshooting
* [Routing](/tools/code-step/examples#routing-with-multiple-conditions) — Return multiple booleans to branch
* [Tool Steps](/flows/steps-tool) — How tool steps and conditions work
