Skip to content

Code Node ​

The Code node allows you to execute custom Python or JavaScript code in your workflow, enabling complex data transformations, business logic, and algorithmic processing. It provides flexible input/output mechanisms to pass workflow data to code and retrieve execution results.

Use Cases ​

Typical Applications ​

  • Complex Data Processing - Implement complex transformation logic beyond workflow expressions
  • Custom Algorithms - Execute specific calculations or algorithmic processing
  • Data Validation - Implement complex data validation rules using code
  • Format Conversion - Convert between different data formats (JSON, XML, CSV, etc.)
  • Business Logic - Implement specific business rules and calculation logic
  • Third-party Library Integration - Leverage rich libraries from Python/JavaScript ecosystems

Node Configuration ​

Basic Settings (Parameters Panel) ​

Code Content (code) ​

The code to execute. This is a required parameter.

Field Properties:

  • Required field
  • Supports Python3 and JavaScript
  • Multi-line code editor
  • Syntax highlighting and auto-completion

Python3 Example:

python
def main(arg1: str, arg2: str):
    return {
        "result": arg1 + arg2,
    }

JavaScript Example:

javascript
function main({arg1, arg2}) {
    return {
        result: arg1 + arg2
    }
}

Programming Language (lang) ​

Select the programming language for the code.

Available Values:

  • python3 - Python 3.x (default)
  • javascript - JavaScript (ES6+)

Input Parameters (inputs) ​

Define input variables to pass to the code.

Field Properties:

  • Array type, can add multiple inputs
  • Each input contains:
    • variable - Variable name (required, must follow variable naming rules)
    • value - Variable value (required, supports expressions)
  • Variable names must be unique
  • Defaults to arg1 and arg2 inputs

Configuration Examples:

javascript
// Input 1
variable: "userMessage"
value: $('Webhook Trigger').body.message

// Input 2
variable: "userId"
value: $('Webhook Trigger').body.userId

// Input 3
variable: "timestamp"
value: new Date().toISOString()

Output Variables (outputs) ​

Define output variables returned by code and their types.

Field Properties:

  • Array type, can add multiple outputs
  • Each output contains:
    • variable - Variable name (required, must follow variable naming rules)
    • type - Data type (required)
  • Variable names must be unique
  • Defaults to one result output (type string)

Supported Data Types:

  • string - String
  • number - Number
  • boolean - Boolean
  • object - Object
  • array[string] - String array
  • array[number] - Number array
  • array[boolean] - Boolean array
  • array[object] - Object array

Configuration Examples:

javascript
// Output 1
variable: "result"
type: "string"

// Output 2
variable: "count"
type: "number"

// Output 3
variable: "items"
type: "array[object]"

Advanced Settings (Settings Panel) ​

Always Output (alwaysOutput) ​

Whether to output an empty item when output is empty.

Default: false

Purpose: Prevents workflow from terminating at this node, ensuring subsequent nodes can execute.

Execute Once (executeOnce) ​

Whether to execute only once using data from the first input item.

Default: false

Purpose:

  • By default, code executes for each item when upstream nodes return multiple items
  • Enable this to execute only for the first item, improving performance

Retry on Fail (retryOnFail) ​

Whether to automatically retry when code execution fails.

Default: false

Max Tries (maxTries) ​

Maximum number of retries after failure.

Default: 3

Prerequisite: retryOnFail must be true

Wait Between Tries (waitBetweenTries) ​

Wait time between retries (milliseconds).

Default: 1000 (1 second)

Prerequisite: retryOnFail must be true

Error Handling (onError) ​

How to handle code execution failures.

Available Values:

  • stopWorkflow - Stop entire workflow (default)
  • continueRegularOutput - Continue with regular output
  • continueErrorOutput - Continue with error output

Node Description (nodeDescription) ​

Add custom description for the node.

yaml
nodeDescription: "Process user input and calculate recommendation results"

Code Writing Guide ​

Python3 Code Standards ​

Basic Structure ​

python
def main(arg1, arg2, arg3):
    # Your code logic

    # Return dictionary where keys match output variable names
    return {
        "result": "processing result",
        "count": 42,
        "items": [1, 2, 3]
    }

Type Annotations ​

python
def main(user_id: str, score: int) -> dict:
    return {
        "message": f"User {user_id} scored {score}"
    }

Error Handling ​

python
def main(data: str):
    try:
        parsed = json.loads(data)
        return {"result": parsed}
    except Exception as e:
        raise ValueError(f"JSON parsing failed: {str(e)}")

Using Standard Library ​

python
import json
import re
from datetime import datetime

def main(text: str):
    # Extract emails using regex
    emails = re.findall(r'[\w\.-]+@[\w\.-]+', text)

    return {
        "emails": emails,
        "count": len(emails),
        "timestamp": datetime.now().isoformat()
    }

JavaScript Code Standards ​

Basic Structure ​

javascript
function main({arg1, arg2, arg3}) {
    // Your code logic

    // Return object where keys match output variable names
    return {
        result: "processing result",
        count: 42,
        items: [1, 2, 3]
    }
}

Arrow Functions ​

javascript
const main = ({userId, score}) => {
    return {
        message: `User ${userId} scored ${score}`
    }
}

Error Handling ​

javascript
function main({data}) {
    try {
        const parsed = JSON.parse(data)
        return {result: parsed}
    } catch (e) {
        throw new Error(`JSON parsing failed: ${e.message}`)
    }
}

Using Modern JavaScript ​

javascript
function main({items, threshold}) {
    // Array operations
    const filtered = items.filter(item => item.value > threshold)
    const mapped = filtered.map(item => ({
        ...item,
        processed: true
    }))

    // Object spreading
    const result = {
        items: mapped,
        total: mapped.length,
        timestamp: new Date().toISOString()
    }

    return result
}

Output Data ​

Code node outputs are determined by variables defined in outputs.

javascript
// Access individual output variables
$('Code').result
$('Code').count
$('Code').items

// Access array outputs
$('Code').items[0]
$('Code').items.length

// Access object outputs
$('Code').data.name
$('Code').data.age

Workflow Examples ​

Example 1: Data Cleaning and Validation ​

Webhook Trigger
  → Code Node
    Language: Python3
    Inputs:
      - email: $('Webhook Trigger').body.email
      - phone: $('Webhook Trigger').body.phone
    Code:
      import re

      def main(email: str, phone: str):
          # Validate email
          email_valid = bool(re.match(r'^[\w\.-]+@[\w\.-]+\.\w+$', email))

          # Clean phone number (remove non-digits)
          phone_clean = re.sub(r'\D', '', phone)
          phone_valid = len(phone_clean) == 11

          return {
              "email_valid": email_valid,
              "phone_valid": phone_valid,
              "phone_clean": phone_clean,
              "all_valid": email_valid and phone_valid
          }
    Outputs:
      - email_valid: boolean
      - phone_valid: boolean
      - phone_clean: string
      - all_valid: boolean
  → Conditional Branch
    Condition: $('Code').all_valid === true

Example 2: Complex Business Calculations ​

HTTP Request (Query order data)
  → Code Node
    Language: JavaScript
    Inputs:
      - orders: $('HTTP Request').body.orders
      - taxRate: 0.13
    Code:
      function main({orders, taxRate}) {
          // Calculate order statistics
          const stats = orders.reduce((acc, order) => {
              const subtotal = order.items.reduce((sum, item) =>
                  sum + (item.price * item.quantity), 0)
              const tax = subtotal * taxRate
              const total = subtotal + tax

              return {
                  count: acc.count + 1,
                  subtotal: acc.subtotal + subtotal,
                  tax: acc.tax + tax,
                  total: acc.total + total
              }
          }, {count: 0, subtotal: 0, tax: 0, total: 0})

          return {
              orderCount: stats.count,
              subtotal: stats.subtotal.toFixed(2),
              tax: stats.tax.toFixed(2),
              total: stats.total.toFixed(2),
              avgOrderValue: (stats.total / stats.count).toFixed(2)
          }
      }
    Outputs:
      - orderCount: number
      - subtotal: string
      - tax: string
      - total: string
      - avgOrderValue: string
  → Answer Node

Example 3: Text Processing and Analysis ​

Chat Trigger
  → Code Node
    Language: Python3
    Inputs:
      - text: $('Chat Trigger').message
    Code:
      import re
      from collections import Counter

      def main(text: str):
          # Clean text
          text_clean = re.sub(r'[^\w\s]', '', text.lower())

          # Tokenize (simple space split)
          words = text_clean.split()

          # Count word frequency
          word_freq = Counter(words)
          top_words = word_freq.most_common(5)

          # Basic statistics
          stats = {
              "char_count": len(text),
              "word_count": len(words),
              "unique_words": len(word_freq),
              "top_words": [{"word": w, "count": c} for w, c in top_words],
              "avg_word_length": sum(len(w) for w in words) / len(words) if words else 0
          }

          return stats
    Outputs:
      - char_count: number
      - word_count: number
      - unique_words: number
      - top_words: array[object]
      - avg_word_length: number
  → LLM Node (Generate response based on analysis)

Example 4: JSON Transformation ​

Webhook Trigger
  → Code Node
    Language: JavaScript
    Inputs:
      - data: $('Webhook Trigger').body
    Code:
      function main({data}) {
          // Transform flat structure to nested structure
          const transformed = {
              user: {
                  id: data.user_id,
                  name: data.user_name,
                  email: data.user_email,
                  profile: {
                      age: data.age,
                      gender: data.gender
                  }
              },
              order: {
                  id: data.order_id,
                  amount: data.amount,
                  status: data.status
              },
              meta: {
                  timestamp: new Date().toISOString(),
                  source: 'webhook'
              }
          }

          return {result: transformed}
      }
    Outputs:
      - result: object
  → HTTP Request (Send transformed data)

Example 5: Data Filtering and Sorting ​

Knowledge Retrieval
  → Code Node
    Language: Python3
    Inputs:
      - results: $('Knowledge Retrieval').results
      - minScore: 0.7
      - maxResults: 5
    Code:
      def main(results: list, minScore: float, maxResults: int):
          # Filter low-score results
          filtered = [r for r in results if r.get('score', 0) >= minScore]

          # Sort by score
          sorted_results = sorted(filtered, key=lambda x: x.get('score', 0), reverse=True)

          # Limit count
          top_results = sorted_results[:maxResults]

          # Format output
          formatted = [
              {
                  "title": r.get('title', ''),
                  "content": r.get('content', '')[:200],  # First 200 chars
                  "score": round(r.get('score', 0), 3),
                  "source": r.get('metadata', {}).get('source', 'unknown')
              }
              for r in top_results
          ]

          return {
              "results": formatted,
              "total": len(formatted),
              "filtered_count": len(filtered) - len(top_results)
          }
    Outputs:
      - results: array[object]
      - total: number
      - filtered_count: number
  → LLM Node

Best Practices ​

1. Reasonable Input/Output Usage ​

Clearly Define Inputs and Outputs

python
# Clear input/output definition
Inputs:
  - userId: $('Webhook Trigger').body.userId
  - action: $('Webhook Trigger').body.action
  - timestamp: new Date().getTime()

Outputs:
  - success: boolean
  - message: string
  - data: object

Avoid Too Many Inputs

javascript
// Too many inputs - combine related data into object
inputs: ["field1", "field2", "field3", ...] // Too many

// Better approach
input: "userData"
value: {
  field1: $('Node').field1,
  field2: $('Node').field2,
  // ...
}

2. Error Handling ​

Use try-catch

python
def main(data: str):
    try:
        result = complex_operation(data)
        return {"success": True, "result": result}
    except ValueError as e:
        return {"success": False, "error": f"Data validation failed: {str(e)}"}
    except Exception as e:
        return {"success": False, "error": f"Unknown error: {str(e)}"}

Validate Inputs

javascript
function main({email, age}) {
    // Input validation
    if (!email || typeof email !== 'string') {
        throw new Error('email must be a non-empty string')
    }

    if (typeof age !== 'number' || age < 0) {
        throw new Error('age must be a non-negative number')
    }

    // Business logic
    return {result: 'ok'}
}

3. Performance Optimization ​

Avoid Unnecessary Loops

javascript
// Inefficient
function main({items}) {
    let result = []
    for (let i = 0; i < items.length; i++) {
        for (let j = 0; j < items.length; j++) {
            // O(n²) complexity
        }
    }
    return {result}
}

// Better approach
function main({items}) {
    const result = items.map(item => process(item)) // O(n)
    return {result}
}

Use Execute Once Option

yaml
# When only need to process first item
settings:
  executeOnce: true

4. Code Readability ​

Add Comments

python
def main(order_data: dict):
    # Step 1: Validate order data
    if not validate_order(order_data):
        raise ValueError("Invalid order data")

    # Step 2: Calculate discount
    discount = calculate_discount(order_data)

    # Step 3: Apply discount and return
    final_amount = order_data['amount'] * (1 - discount)

    return {
        "discount": discount,
        "final_amount": round(final_amount, 2)
    }

Use Meaningful Variable Names

javascript
// Bad
function main({x, y}) {
    const z = x + y
    return {r: z}
}

// Good
function main({price, tax}) {
    const totalAmount = price + tax
    return {totalAmount}
}

5. Security Considerations ​

Don't Hardcode Sensitive Information

python
# Don't do this
def main(data: str):
    api_key = "sk-xxxxxxxxxxxxx"  # Hardcoded
    # ...

# Should pass through input parameter
def main(data: str, api_key: str):
    # Use api_key
    # ...

Input Validation and Sanitization

javascript
function main({userInput}) {
    // Sanitize user input to prevent injection attacks
    const cleaned = userInput.replace(/[<>]/g, '')

    return {cleaned}
}

FAQ ​

Q1: Which Python/JavaScript versions does the Code node support? ​

A:

  • Python: Python 3.x (specific version depends on runtime environment)
  • JavaScript: ES6+ syntax, supports modern JavaScript features

Q2: Can I use third-party libraries in code? ​

A: Depends on runtime environment configuration:

  • Python: Usually supports standard library (json, re, datetime, etc.)
  • JavaScript: Supports ES6+ built-in objects and methods
  • Third-party library support requires pre-installation in runtime environment

Q3: Is there a time limit for code execution? ​

A: Yes, there's usually an execution timeout limit (e.g., 30 seconds) to prevent infinite execution. When writing code:

  • Avoid infinite loops
  • Optimize algorithm complexity
  • Use batch processing for large datasets

Q4: What are the naming rules for input/output variables? ​

A:

  • Must start with a letter or underscore
  • Can only contain letters, numbers, underscores
  • Cannot use Python/JavaScript reserved words
  • Case-sensitive
  • Recommend meaningful camelCase or snake_case naming

Valid Examples:

userId, user_name, _temp, data1

Invalid Examples:

1user (starts with number)
user-name (contains hyphen)
class (reserved word)

Q5: Must code return values exactly match output definitions? ​

A: Yes. The keys in the object returned by code must match the variable names defined in outputs.

Example:

javascript
// Output definition
outputs: [
  {variable: "result", type: "string"},
  {variable: "count", type: "number"}
]

// Code must return
return {
  result: "some string",
  count: 42
}

// Missing fields or mismatched field names will cause errors

Q6: How to choose between Python and JavaScript? ​

A: Consider these factors:

  • Python:

    • Better for data processing and scientific computing
    • More concise and readable code
    • Rich standard library (regex, date handling, etc.)
  • JavaScript:

    • Better for JSON data operations
    • More flexible object and array operations
    • Better match with frontend data structures

Recommendation: Prioritize the language your team is most familiar with.

Q7: Can the Code node call external APIs? ​

A: Generally not recommended to call external APIs directly in Code node:

  • Use HTTP Request node to call external APIs
  • Code node should focus on data processing and transformation logic
  • This better leverages HTTP node's error handling, retry features

Q8: How to debug the Code node? ​

A: Debugging suggestions:

  1. Use Answer node to output intermediate results

    python
    def main(data: str):
        intermediate = process_step1(data)
        # Return intermediate result for inspection
        return {"intermediate": str(intermediate)}
  2. Add detailed error messages

    python
    try:
        result = process(data)
    except Exception as e:
        return {"error": f"Processing failed: {str(e)}, data: {data}"}
  3. Return step-by-step results

    python
    return {
        "step1_result": step1,
        "step2_result": step2,
        "final_result": final
    }
  4. Use workflow logs - View node execution logs and error details

Next Steps ​