runCode

Platform 6.4.0+

The runCode task executes a Python script directly in a workflow. Use it to replace combinations of existing canvas tasks, such as chains of JSON Schema Transformations (JSTs), query tasks, and merge tasks, with a single, readable Python script.

The task uses Itential Automation Gateway (IAG) to create a virtual Python environment and execute the script.

Prerequisites

Before using the runCode task, ensure the following:

  • Register an active IAG 5.4.0 or later cluster with Itential Platform using Gateway Manager. For information, see Create cluster in Gateway Manager.
  • Ensure the Python version on the IAG 5 host is compatible with your scripts and packages. The task uses the default Python interpreter on the host, which is the version invoked by python or python3 on the iagctl command line. IAG does not enforce a minimum version. To check, run python --version on the IAG 5 host.
  • Ensure the gateway:code role from GatewayManager is assigned to your group. Contact your administrator to have this role assigned.

Potential use cases

Use this task when existing canvas tasks become unwieldy for the logic you need to express. Common scenarios include:

  • Replacing a chain of JST tasks that extract, filter, and aggregate API response data
  • Performing data aggregation, calculation, or text processing on task outputs
  • Reshaping nested JSON structures for consumption by downstream tasks

Task properties

Incoming

VariableTypeRequiredDescription
clusterIdStringYesThe active IAG 5 cluster that executes the script.
languageStringYesThe script language. Set to python.
codeStringYesThe Python script to execute. Limited to 2 MB.
safety.timeoutIntegerYesExecution timeout in seconds. Range: 1–1000 seconds. Default: 1 second.
packagesArrayNoA list of pip package specs to install into the virtual Python environment before execution. For example: ["requests>=2.28.0", "pandas==2.0.0"].
dataObjectNoInput data for your script. Keys defined here are accessible in your script via stdin.

Outgoing

The task returns all output fields as properties of the result outgoing variable.

FieldTypeDescription
result.stdoutStringRaw string of everything the script printed to stdout.
result.stdout_jsonAnyThe stdout content parsed as JSON. Present only when stdout is valid JSON.
result.stderrStringEverything your script writes to stderr, including debug messages and exception tracebacks.
result.statusStringExecution status: completed or error.
result.return_codeInteger or nullProcess exit code. 0 indicates success.
result.started_atStringISO 8601 timestamp when execution started.
result.finished_atStringISO 8601 timestamp when execution completed.
result.elapsed_msNumberServer-measured execution time in milliseconds.

Error

This field appears in the task response only when result.status is error.

FieldTypeDescription
result.errorStringPlatform-specific failure reason, such as a timeout.

Use runCode in a workflow

The following sections walk through configuring the task, mapping inputs from upstream tasks, and referencing outputs in downstream tasks.

Configure the task

The runCode task is configured across two surfaces: the task panel and the code editor. See Configure and manage tasks for the general task configuration pattern.

1

Select a cluster

In the task panel, select the active IAG 5 cluster from the Cluster dropdown.
2

Open the code editor

Click Open Editor in the task panel.
3

Add packages

In the Packages tab, click + Add Package. Enter the package name, select a version constraint, and enter a version number if needed. IAG 5 installs packages from the public PyPI index by default. To restrict available packages, configure your IAG 5 host at the OS or network level.
4

Set the timeout

Set a value in seconds in the Timeout field at the top of the editor.
5

Write your script

Write your Python script in the code area.

To test before saving, click Run Code. The result appears in the Outputs tab. To test with specific input values, add key:value pairs in the Inputs tab. These values are saved across sessions but do not affect workflow execution.

Configure data inputs

Configure the keys and their sources in the task’s Data tab.

Variable SourceWhen to use
taskPass output from an upstream task. Also set Previous Task and Task Variable.
staticPass a hard-coded value.
jobPass a job variable.

For example, to pass the output of an upstream getDevices task into your script as devices, add a key named devices and set Previous Task to getDevices with the appropriate reference variable.

Reference runCode output in downstream tasks

To use the runCode output in a downstream task, configure that task’s input with:

  • Previous Task: the runCode task
  • Task Variable: result.stdout_json for the parsed JSON result, or any other result field

If you need a specific nested value from result.stdout_json, use a task query to extract it directly on the input field without adding a query task to the canvas. See Task query for details.

Errors and timeout

The task catches unhandled Python exceptions and captures the traceback in result.stderr. The task still completes and the workflow does not follow the error transition.

The Timeout (safety.timeout) stops execution if exceeded. When the timeout is exceeded, result.status becomes error and result.error contains the Platform-specific failure reason. The timeout applies to your code only, not to package installation.

If the task cannot run on the gateway, for example, if the gateway is not enabled or loses connectivity, the task itself fails and no result output is produced. The error is visible in the task’s Error tab in Operations Manager. For example:

1{
2 "state": "Error",
3 "domain": "gateway_manager",
4 "code": 503,
5 "timestamp": "2026-04-28T16:20:02.092Z",
6 "message": "Gateway with id test-code-task is not enabled"
7}

Size limit

Code is limited to 2 MB. You cannot save code that exceeds this limit. The limit applies to code text only. Installed packages do not count toward it.

Package caching

The first time you run a task with a new set of packages, the runner installs them into a virtual environment. Subsequent runs reuse the cached environment, so there’s no install overhead. Any change to the packages list triggers a fresh install.

Example: filter a device list by status

This example filters a list of devices to return only those with an active status. It replaces the equivalent JST filter operation with a single readable script.

Data inputs

Configure one key in the data object in the Inputs tab:

KeySource
devicesOutput of the upstream task that retrieves your device inventory

Sample input

1{
2 "devices": [
3 {"hostname": "router-01", "ip": "10.0.0.1", "status": "active"},
4 {"hostname": "router-02", "ip": "10.0.0.2", "status": "inactive"},
5 {"hostname": "switch-01", "ip": "10.0.0.3", "status": "active"}
6 ]
7}

Script

1import sys, json
2
3data = json.load(sys.stdin)
4devices = data.get('devices', [])
5
6# Keep only devices with an active status
7active_devices = [d for d in devices if d.get('status') == 'active']
8
9print(json.dumps({'devices': active_devices, 'total': len(active_devices)}))

Output

Downstream tasks access the result as result.stdout_json:

1{
2 "devices": [
3 {"hostname": "router-01", "ip": "10.0.0.1", "status": "active"},
4 {"hostname": "switch-01", "ip": "10.0.0.3", "status": "active"}
5 ],
6 "total": 2
7}

Troubleshoot

Use the following to troubleshoot errors and issues.

Execution status vs. exit code

result.status and result.return_code communicate different types of failure:

  • status: completed with return_code: 0 means the script ran and exited cleanly.
  • status: completed with a non-zero return_code means the script ran but exited with a failure code. Your code executed; the script itself signaled failure.
  • status: error indicates a Platform-level failure, such as a timeout. The script may not have run, or it stopped mid-execution. Check result.error for details. Gateway connectivity failures produce a different outcome. The task itself errors and no result fields are populated, because a task failure is distinct from a task error. See Errors and timeout.

stdout_json absent after a successful run

If result.stdout_json does not appear after a successful execution (return_code: 0), the most common causes are:

  • stdout contained non-JSON content, a mix of JSON and other output, or no output
  • A type in the output object was not JSON-serializable, causing json.dumps() to raise a TypeError and write a traceback to stderr instead of JSON to stdout

Inspect result.stdout and result.stderr directly to determine which applies.