Skip to content

Script Steps (JavaScript, Python, Bash)

Use multi-language script steps in workflows via the Script Execution Service (SES).

Internal reference: internal/SCRIPT_STEPS_GUIDE.md. Step type overview: Step Types.

Overview

When SES is enabled (ORCH_SES_ENABLED=true):

Step type SES runtime
javascript QuickJS sandbox
python CPython subprocess
bash /bin/bash subshell

Recommended production posture: ORCH_SES_ENABLED=true, ORCH_SES_FALLBACK_TO_INLINE_JS=false, ORCH_ENABLE_INLINE_JS=false.

Unified contract

Every script has access to:

Variable Description
input Step input (from previous step or initial payload)
context Workflow context (workflow_id, run_id, user_id, …)
result Must be assigned — becomes step output
// JavaScript
result = input.toUpperCase();
# Python
result = input.upper()
# Bash
result=$(echo "$input" | tr '[:lower:]' '[:upper:]')

Examples

JavaScript

steps:
  - id: parse_date
    type: javascript
    input_from: initial
    code: |
      result = new Date().toISOString();

Runs in QuickJS. require() and eval() are blocked by default.

Python

steps:
  - id: filter_records
    type: python
    input_from: previous
    code: |
      import json
      data = json.loads(input)
      records = [r for r in data['items'] if r['status'] == 'active']
      result = json.dumps(records)

Standard library available; dangerous imports (os, sys, …) blocked in allowlist mode.

Bash

steps:
  - id: count_lines
    type: bash
    input_from: previous
    code: |
      result=$(echo "$input" | wc -l)

Shell utilities (grep, sed, awk, …) available; dangerous commands blocked.

Language selection

Use case Language
JSON parsing, quick transforms JavaScript
Complex logic, standard library Python
Text processing, CLI-style ops Bash

Configuration

Orchestrator

ORCH_SES_ENABLED=true
ORCH_SES_URL=http://ses:8080
ORCH_SES_FALLBACK_TO_INLINE_JS=false
ORCH_SES_TIMEOUT_SECONDS=10
ORCH_ENABLE_INLINE_JS=false

See also Tuning, Limits & Load Testing.

SES service

SES_PYTHON_ENABLED=true
SES_BASH_ENABLED=true
SES_JAVASCRIPT_ENABLED=true
SES_SECURITY_MODE=allowlist
SES_MAX_CODE_SIZE=102400          # 100 KB
SES_MAX_OUTPUT_BYTES=52428800     # 50 MB

Security

Allowlist mode blocks dangerous patterns:

  • Python: __, eval, exec, open, os, sys
  • Bash: rm, dd, /dev/ redirects
  • JavaScript: eval, dynamic Function(), require

All executions are audited (workflow, step, runtime, duration, code hash).

Troubleshooting

Symptom Cause Fix
"SES client not available" SES not deployed or unreachable Check ORCH_SES_ENABLED and ORCH_SES_URL
"Code too large" Script exceeds size limit Split into multiple steps
Allowlist blocked Blocked keyword/import Refactor or adjust allowlist config
Timeout Script too slow Optimize or increase ORCH_SES_TIMEOUT_SECONDS