Code — Run custom Python logic against one explicit input value
Run arbitrary Python logic inside a workflow node. The Code node gives you a full Python function body with access to the upstream input value and workflow context.
Use Code when:
- You need logic that cannot be expressed with Transform, If, or Switch (loops, calculations, string manipulation, data processing)
- You want to use a Python standard library module that is not available as a built-in plugin
- You need to transform arrays, perform arithmetic, or build complex conditional logic
- You want full control over the output object shape
| Handle | Type | Description |
|---|---|---|
input | any | The upstream value passed into your function as the input variable. Optional — if nothing is connected, input is None. |
| Handle | Type | Description |
|---|---|---|
result | object | The dictionary returned by your Python code on the success path. |
The result is accessed in downstream nodes as {{ code.* }}. Reference fields from the returned dict directly (e.g., {{ code.message }}, {{ code.url }}).
| Setting | Type | Default | Description |
|---|---|---|---|
language | enum | python | Execution language. Currently only python is supported. |
code | code editor (Python) | See below | Python function body. Must return a dictionary. The input and ctx variables are pre-injected. |
Default code:
# input is available as the upstream value
# ctx.workflow_id and ctx.run_id are available
return {"result": input}
Your code runs inside an async Python function. The following variables are available:
| Variable | Type | Description |
|---|---|---|
input | any | The value connected to the input handle |
ctx.workflow_id | string | The current workflow's ID |
ctx.run_id | string | The current execution run's ID |
Return a dictionary with the fields you want downstream nodes to access:
return {
"result": input["amount"] * 1.1,
"formatted": f"${input['amount'] / 100:.2f}"
}
Access environment variables with the standard library:
import os
api_key = os.environ.get("MY_API_KEY", "")
Only Python standard library imports are allowed in managed execution. Packages listed in the workflow's Python dependencies are installed automatically at runtime — add them through workflow settings, not inside the code node.
Extract the most recent commit from a GitHub push event and format a Slack message:
Webhook → Code → Slack Send Message
Code settings:
commits = input.get("commits", [])
if not commits:
return {"message": "No commits in this push."}
latest = commits[0]
return {
"message": f"New commit by {latest['author']['name']}: {latest['message'][:80]}",
"url": latest["url"],
"author": latest["author"]["name"]
}
Downstream nodes reference {{ code.message }}, {{ code.url }}, and {{ code.author }}.
import webhook from @tensorify/webhook-trigger:4.0.0
import code_node from @tensorify/code:3.0.0
import http_request from @tensorify/http-request:3.0.0
node trigger @tensorify/webhook-trigger:4.0.0 {
path = "/github/push"
method = "POST"
provider = "github"
}
node format @tensorify/code:3.0.0 {
language = "python"
code = "commits = input.get(\"commits\", [])\nif not commits:\n return {\"message\": \"No commits.\"}\nlatest = commits[0]\nreturn {\"message\": latest[\"message\"], \"author\": latest[\"author\"][\"name\"]}"
}
node notify @tensorify/http-request:3.0.0 {
method = "POST"
url = "https://hooks.slack.com/services/{{ env.SLACK_WEBHOOK_PATH }}"
}
trigger.payload -> format.input
format.result -> notify.body
Code has a hidden On Error control output branch. Enable it via the "Error output handle" toggle at the bottom of the settings panel, or connect an edge to error in TSL (which enables it automatically).
The error branch fires when:
- The code setting is empty or missing
- An unhandled exception occurs during execution
- The return value is not a dictionary (e.g., returning a string, list, or
None) - An unsupported language is configured
When the error branch executes, downstream nodes can access the error details via {{ <nodeId>__error }}:
| Field | Type | Description |
|---|---|---|
error | string | Human-readable error message (e.g., Code execution failed: ...) |
nodeId | string | The ID of the node that failed |
If the error branch is not connected, any of the above failures halt execution on that path.
Use try/except inside your code for expected failures you want to handle inline, and reserve the error branch for unexpected runtime failures.
import code_node from @tensorify/code:3.0.0
import stop from @tensorify/stop:3.0.0
node process @tensorify/code:3.0.0 {
code = "return {\"total\": sum(input[\"values\"])}"
}
node halt @tensorify/stop:3.0.0
process.error -> halt.input
- Return type: Your code must
returna dictionary. ReturningNone, a string, a list, or forgetting the return statement triggers the error branch. - Async context: The function context is async. You can use
awaitfor async operations; standard synchronous code works without it. - Input is optional: If nothing is connected to the
inputhandle,inputisNone. Guard against this withinput or {}or an explicit check. - Standard library only: Third-party imports (e.g.,
requests,pandas) are rejected unless listed in the workflow's Python dependencies. Use built-in plugins like HTTP Request for common integrations. - No
eval/exec: Dynamic code execution builtins are blocked for security.
- Transform — reshape data without code
- HTTP Request — call APIs without code
- If — branch on computed values from Code output
- Environment Variables — store secrets and config
