orchestrator

📁 a1exra/orchestrator-skill 📅 Feb 3, 2026
2
总安装量
2
周安装量
#74348
全站排名
安装命令
npx skills add https://github.com/a1exra/orchestrator-skill --skill orchestrator

Agent 安装分布

opencode 2
codex 2
claude-code 1

Skill 文档

Orchestrator Flow Builder Expert v2.0.0

You are an expert in Papaya Global Payments orchestrator flow development. When invoked, help users build, validate, debug, and understand orchestrator flows using comprehensive knowledge of the codebase.

Table of Contents

  1. Quick Reference
  2. Core Concepts
  3. Task Types Reference
  4. Expression Operators
  5. Advanced Features
  6. Component Library Reference
  7. Common Patterns
  8. Troubleshooting Guide
  9. Validation Rules
  10. Best Practices
  11. Search Strategies

Quick Reference

Task Types Summary

Task Type Purpose Blocking Common Use
SEQUENCE Sequential execution ALL/FIRST/NONE Multi-step workflows
COMPONENT External service call API integrations
SUB_FLOW Nested flow call Reusable logic
TRANSFORM Data manipulation JSON transforms
MAP Batch processing Array iteration
SWITCH Conditional branching Status routing
FORK Parallel execution Independent operations
TRY_CATCH Error handling Failure recovery
EVALUATE Dynamic expressions Runtime evaluation
AWAIT Async operations Wait for events
TAGS Metadata attachment Observability
STATUS Progress reporting Long operations
TERMINATE Flow termination Early exit
SLEEP Delayed execution Rate limiting

Operators Cheat Sheet

Conditional & Control: $$first, $$if, $$switch, $$and, $$or, $$not, $$coalesce Array: $$map, $$filter, $$reduce, $$partition, $$group, $$flat, $$sort, $$at, $$slice, $$concat, $$distinct, $$reverse, $$lookup, $$entries, $$flatten Object: $$object, $$entries, $$keys, $$values, $$merge, $$get, $$wrap, $$normalize, $$flatten, $$unflatten String: $$join, $$split, $$replace, $$substring, $$upper, $$lower, $$trim, $$template, $$test, $$match, $$digest Math: $$math, $$numberparse, $$abs, $$ceil, $$floor, $$round, $$min, $$max Date/Time: $$date (FORMAT, ADD, SUB, DIFF, EPOCH) Type & Validation: $$is, $$isnull, $$boolean, $$length, $$jsonpath, $$jsonvalidate Advanced: $$eval, $$transform, $$uuid, $$base64, $$hash

Special Variables Reference

Variable Scope Purpose Example
#now Global Current timestamp $$date(ADD,DAYS,30):#now
#current Local Current input context #current.field
##current Iterator Current iteration item $$map $.array (x) => ##current.id
##outer Nested Parent iteration context Used in nested $$map
##target Lookup Joined item from $$lookup ##target.field
#env.* Global Environment variables #env.rnd_contact_service_alerts
#caller_id Global Flow execution ID Tracking/logging
#uuid Global Generate UUID Unique identifiers
#null Global Explicit null value Default handling
#exception Catch Error object in TRY_CATCH #exception.error_info
$._init Global Flow input $._init.user_id
$._call Global Call metadata $._call.id

Core Concepts

Context Variables: ##current vs #now vs #env.*

#current – References the current task’s input/scope:

{
  "type": "TRANSFORM",
  "input": {
    "user_name": "#current.user.first_name"  // Access input field
  }
}

##current – References the current iteration item in operators:

{
  "items": "$$map $.users (user) => { \"id\": ##current.id }"
  // ##current refers to each user in the iteration
}

#now – Current timestamp (ISO 8601):

{
  "due_date": "$$date(ADD,DAYS,30):#now"
}

#env.* – Environment-specific configuration:

{
  "alert_email": "#env.rnd_contact_service_alerts",
  "environment": "#env.full_environment_name"
}

Spread Operator (*)

The * operator spreads object properties or array elements:

// Merge objects
{
  "output": {
    "*": "#current.base_object",
    "new_field": "value"
  }
}

// Flatten arrays
{
  "all_items": {
    "*": [
      "$.list1",
      "$.list2"
    ]
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:69:

{
  "to": {
    "index": "##current.index",
    "*": "##current.payment"  // Spread all payment fields
  }
}

Escape Sequences

Use \\$ to output literal $ characters in strings:

{
  "message": "Cost is \\$100"  // Outputs: "Cost is $100"
}

Without escaping, $ would be interpreted as JSONPath.

JSONPath Filtering Syntax

Filter arrays using [?(@.condition)]:

// Get items where payment exists
"payments": "$._init.items[?(@.payment != null)]"

// Get active users
"active": "$.users[?(@.status == 'active')]"

// Complex conditions
"valid": "$.items[?(@.amount > 100 && @.approved == true)]"

Example from flows/fileupload/validate/items/1.0.3.json:35:

"input": "$$first:$._init.items[?(@.payment != null)]"

Comparison Operators in $$is

The $$is operator supports multiple comparison modes:

Operator Syntax Example
Equal eq or = $$is(=,value):$.field
Not equal ne or != $$is(!=,null):$.field
Greater than gt or > $$is(>,100):$.amount
Greater/equal gte or >= $$is(>=,0):$.count
Less than lt or < $$is(<,50):$.score
Less/equal lte or <= $$is(<=,1000):$.limit
In list in $$is(in,['A','B']):$.type
Not in list nin $$is(nin,['X','Y']):$.status

Example from flows/fileupload/validate/items/1.0.3.json:339:

"by": "$$is(>,1):##current[1].length()"

Task Types Reference

SEQUENCE

Sequential task execution with blocking modes.

{
  "type": "SEQUENCE",
  "description": "Execute tasks in order",
  "block": "ALL",  // ALL|FIRST|NONE
  "result": "results",  // Expose results to scope
  "tasks": [...]
}

Blocking Modes:

  • ALL: Wait for all tasks to complete (default)
  • FIRST: Stop after first successful task
  • NONE: Fire-and-forget, don’t wait

Use Cases: Multi-step workflows, ordered operations Search: grep -r '"type": "SEQUENCE"' flows/

COMPONENT

Call external services via components.

{
  "type": "COMPONENT",
  "description": "Call external service",
  "component_id": "standalone.service.operation",
  "component_version": "1.0.0",
  "input": {...},
  "retries": 2,
  "backoff": 100,
  "multiplier": 3,
  "result": "service_response"
}

Retry Configuration:

  • retries: Number of retry attempts (default: 2)
  • backoff: Initial delay in ms (default: 100)
  • multiplier: Backoff multiplier (default: 3)

Use Cases: API calls, service integration Search Components: glob 'components/**/*.json'

SUB_FLOW

Call nested flows with version constraints.

{
  "type": "SUB_FLOW",
  "description": "Call nested flow",
  "flow_id": "admin.security.permissions.check",
  "flow_version": ">=1.0.0 <2.0.0",
  "input": {...},
  "fail_retry_filter": ["ERROR_CODE_1"],
  "result": "sub_flow_result"
}

Version Constraints:

  • ^1.0.0: Compatible with 1.x.x
  • >=1.0.0 <2.0.0: Range constraint
  • 1.0.0: Exact version

Fire-and-Forget Pattern (flows/payments/screening/screen/2.0.2.json):

{
  "type": "SEQUENCE",
  "block": "NONE",  // Don't wait for completion
  "tasks": [
    {
      "type": "SUB_FLOW",
      "flow_id": "background.process",
      "input": {...}
    }
  ]
}

Use Cases: Reusable logic, permission checks, complex workflows Search: grep -r '"type": "SUB_FLOW"' flows/

TRANSFORM

Data manipulation with expression operators.

{
  "type": "TRANSFORM",
  "description": "Transform data",
  "result": "transformed",
  "map": {
    "output_field": "$$first $.input_field1 $.input_field2",
    "items": "$$map $.array_field (item) => { \"id\": $.item.id }",
    "filtered": "$$filter $.items (x) => $$is $.x.active true"
  }
}

Inline Syntax:

{
  "type": "TRANSFORM",
  "input": "$$map $.items (x) => ##current.id"
}

Object Syntax:

{
  "type": "TRANSFORM",
  "input": {
    "$$map": "$.items",
    "to": {
      "id": "##current.id",
      "name": "##current.name"
    }
  }
}

Important: Use $$first at root level only, not nested inside other operators.

Use Cases: Data transformation, field mapping, validation

MAP

Batch processing with parallel execution.

{
  "type": "MAP",
  "description": "Process items in batch",
  "input": "$.items",
  "task": {
    "type": "COMPONENT",
    "component_id": "process.item",
    "input": {
      "item_id": "#current.id"
    }
  },
  "result": "processed_items"
}

Key Features:

  • Processes array elements in parallel
  • Each iteration has access to #current (current item)
  • Returns array of results
  • Failures in one item don’t stop others

Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:28:

{
  "type": "MAP",
  "id": "loop",
  "input": "$._init.items",
  "task": {
    "type": "SEQUENCE",
    "tasks": [
      {
        "type": "TRANSFORM",
        "input": "$$at(-1):$$split(::):#current.payee.id"
      }
    ]
  }
}

Use Cases: Bulk operations, parallel processing, batch imports Search: grep -r '"type": "MAP"' flows/

SWITCH

Conditional branching with cases.

{
  "type": "SWITCH",
  "description": "Branch on condition",
  "result": "branch_result",  // IMPORTANT: Expose result for scope
  "cases": [
    {
      "condition": "$$is $.status \"approved\"",
      "task": {...}
    }
  ],
  "default": {...}
}

Evaluation:

  • Cases evaluated in order
  • First matching case executes
  • default executes if no case matches
  • Missing result field causes scope errors in subsequent tasks

Use Cases: Conditional logic, status-based routing Common Issue: Missing result field causes scope errors

FORK

Parallel execution with result aggregation.

{
  "type": "FORK",
  "description": "Execute in parallel",
  "result": "parallel_results",
  "tasks": [...]
}

Key Differences from MAP:

  • FORK: Fixed number of parallel tasks (defined in JSON)
  • MAP: Dynamic parallel processing based on input array

Use Cases: Independent operations, parallel API calls Search: grep -r '"type": "FORK"' flows/

TRY_CATCH

Error handling with typed catches.

{
  "type": "TRY_CATCH",
  "description": "Handle errors",
  "try": {...},
  "catches": [
    {
      "codes": ["VALIDATION_ERROR"],
      "task": {...}
    }
  ],
  "default": {...}
}

Error Object (#exception):

{
  "code": "ERROR_CODE",
  "message": "Error description",
  "error_info": {
    "errors": [
      {
        "properties": ["field.path"],
        "description": "Error detail"
      }
    ]
  }
}

Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:263:

{
  "default": {
    "type": "TRANSFORM",
    "input": {
      "$$transform": {
        "$$if": "$$not:$$isnull:#exception.error_info.errors[0].properties",
        "then": {
          "message": {
            "$$join": [
              "$$at(-1):$$split(\\.):#exception.error_info.errors[0].properties[0]",
              " ",
              "#exception.error_info.errors[0].description"
            ]
          }
        },
        "else": "#exception"
      }
    }
  }
}

Use Cases: Error recovery, validation handling, external service failures Best Practice: Always wrap risky operations (COMPONENT, SUB_FLOW)

EVALUATE

Dynamic expression evaluation at runtime.

{
  "type": "EVALUATE",
  "description": "Evaluate dynamic expression",
  "expression": "$.dynamic_expression_string",
  "result": "evaluated_result"
}

Key Features:

  • Evaluates expressions stored as strings
  • Useful for user-defined rules
  • Can reference scope variables
  • Runtime validation

Use Cases: Dynamic rules, user-defined logic, conditional expressions Search: grep -r '"type": "EVALUATE"' flows/

AWAIT

Wait for async operations or external events.

{
  "type": "AWAIT",
  "description": "Wait for async operation",
  "event": "payment.completed",
  "timeout": 300000,  // 5 minutes in ms
  "result": "event_data"
}

Timeout Configuration:

  • timeout: Maximum wait time in milliseconds
  • If timeout expires, flow terminates with error
  • Use TRY_CATCH to handle timeout gracefully

Use Cases: Webhook callbacks, async processing, event-driven flows Search: grep -r '"type": "AWAIT"' flows/

TAGS

Attach metadata for tracking.

{
  "type": "TAGS",
  "description": "Tag for observability",
  "tags": {
    "entity_id": "$.entity.id",
    "operation": "payment_send"
  }
}

Use Cases: Logging, tracking, debugging Best Practice: Tag at flow start for context

STATUS

Report status to orchestrator.

{
  "type": "STATUS",
  "description": "Report processing status",
  "status": "PROCESSING",
  "message": "Payment validation in progress"
}

Use Cases: Long-running flows, progress tracking

TERMINATE

Stop flow execution.

{
  "type": "TERMINATE",
  "description": "Stop execution",
  "fail": false,  // true for failure, false for success
  "code": "EARLY_EXIT",
  "message": "Condition not met"
}

Use Cases: Early exit, validation failures

SLEEP

Delayed execution.

{
  "type": "SLEEP",
  "description": "Wait before retry",
  "duration": 5000  // milliseconds
}

Use Cases: Rate limiting, scheduled operations, retry delays


Expression Operators

Conditional & Control Flow (7 operators)

$$first – Fallback Values

Returns first non-null value. MUST be at root level, not nested.

Syntax:

"field": "$$first $.optional_field $.default_value"

Object Form:

{
  "field": {
    "$$first": [
      "$.optional_field1",
      "$.optional_field2",
      "default_value"
    ]
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:192:

{
  "target_currency": {
    "$$first": [
      "##target.bank_details.currency",
      "##target.target.currency"
    ]
  }
}

Use Case: Provide fallback values for optional fields Search: grep '$$first' flows/

$$if – Conditional Expression

Ternary conditional operator.

Syntax:

"field": "$$if ($$is $.status \"approved\") $.approved_value $.rejected_value"

Object Form:

{
  "field": {
    "$$if": "##current.condition",
    "then": "value_if_true",
    "else": "value_if_false"
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:206:

{
  "missing": {
    "$$if": "##target.id",
    "then": false,
    "else": true
  }
}

Use Case: Conditional value assignment Search: grep '$$if' flows/

$$switch – Switch Statement

Multi-case conditional branching.

Syntax:

{
  "field": {
    "$$switch": "$.status",
    "cases": {
      "approved": "Approved value",
      "pending": "Pending value",
      "default": "Default value"
    }
  }
}

Nested Example from flows/fileupload/validate/items/1.0.3.json:239:

{
  "enforce_whole_number": {
    "default": false,
    "$$switch": "whole_amount",
    "cases": {
      "default": {
        "whole_amount": false
      },
      "$$switch": "##current.currency",
      "cases": "$.payment_validation_config"
    }
  }
}

Use Case: Multi-branch conditional logic Search: grep '$$switch' flows/

$$and – Logical AND

Returns true if all conditions are true.

Syntax:

"valid": "$$and [$$is $.amount > 0, $$is $.status \"active\"]"

Example from flows/fileupload/validate/items/1.0.3.json:283:

{
  "by": {
    "$$and": [
      "$$is(>,##current.amount):##current.min_amount",
      "$$is(=,##current.target_currency):##current.currency"
    ]
  }
}

Use Case: Combine multiple conditions Search: grep '$$and' flows/

$$or – Logical OR

Returns true if any condition is true.

Syntax:

"valid": "$$or [$$is $.type \"A\", $$is $.type \"B\"]"

Example from flows/fileupload/validate/items/1.0.3.json:181:

{
  "on": {
    "$$or": [
      "$$is(=,##target.source.id):##current.payment.target.id",
      "$$is(=,##target.payee.id):##current.payment.target.id"
    ]
  }
}

Use Case: Alternative conditions Search: grep '$$or' flows/

$$not – Logical NOT

Negates boolean value.

Syntax:

"inactive": "$$not:$.active"

Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:263:

{
  "$$if": "$$not:$$isnull:#exception.error_info.errors[0].properties"
}

Use Case: Boolean negation Search: grep '$$not' flows/

$$coalesce – First Non-Null

Similar to $$first but with different syntax.

Syntax:

"value": "$$coalesce [$.field1, $.field2, \"default\"]"

Use Case: Fallback chain for null values Search: grep '$$coalesce' flows/

Array Operations (15 operators)

$$map – Array Transformation

Transform each array element.

Syntax:

"items": "$$map $.array (item) => { \"id\": ##current.id }"

Object Form:

{
  "items": {
    "$$map": "$.array",
    "to": {
      "id": "##current.id",
      "name": "##current.name"
    }
  }
}

Context Variables:

{
  "$$map": "$.items",
  "context": {
    "##outer": "##current"
  },
  "to": {
    "item_id": "##current.id",
    "parent_ref": "##outer.parent_id"
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:67:

{
  "$$map": "$._init.items[?(@.payment != null)]",
  "to": {
    "index": "##current.index",
    "*": "##current.payment"
  }
}

Use Case: Transform arrays Search: grep '$$map' flows/

$$filter – Array Filtering

Filter array elements by condition.

Syntax:

"active": "$$filter $.items (x) => $$is $.x.active true"

Object Form:

{
  "active": {
    "$$filter": "$.items",
    "by": "##current.active"
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:266:

{
  "$$filter": "$.get_config_for_targets",
  "by": "##current.missing"
}

Use Case: Filter arrays by conditions Search: grep '$$filter' flows/

$$reduce – Array Reduction

Reduce array to single value.

Syntax:

{
  "total": {
    "$$reduce": "$.amounts",
    "init": 0,
    "by": "$$math(ADD) [##accumulator, ##current]"
  }
}

Variables:

  • ##accumulator: Current accumulated value
  • ##current: Current array item

Use Case: Sum, concatenate, aggregate arrays Search: grep '$$reduce' flows/

$$partition – Split Array

Split array into chunks.

Syntax:

{
  "batches": {
    "$$partition": "$.items",
    "size": 100
  }
}

Returns: Array of arrays, each with max size elements

Use Case: Batch processing, pagination Search: grep '$$partition' flows/

$$group – Group By Key

Group array elements by key.

Syntax:

{
  "grouped": {
    "$$group": "$.items",
    "by": "##current.category"
  }
}

Returns: Object with keys as group values, values as arrays

Example from flows/fileupload/validate/items/1.0.3.json:329:

{
  "$$group": {
    "$$map": "$._init.items[?(@.payment.id != null)]",
    "to": {
      "id": "##current.payment.id",
      "index": "##current.index"
    }
  },
  "by": "##current.id"
}

Use Case: Group items by field Search: grep '$$group' flows/

$$flat – Flatten Array

Flatten nested arrays one level.

Syntax:

"flattened": "$$flat [$.array1, $.array2]"

Object Form:

{
  "flattened": {
    "$$flat": [
      "$.array1",
      "$.array2"
    ]
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:173:

{
  "with": {
    "$$flat": [
      "$.find_targets.items[*]",
      "$._init.items[*].beneficiary"
    ]
  }
}

Use Case: Merge multiple arrays Search: grep '$$flat' flows/

$$sort – Sort Array

Sort array by field or comparator.

Syntax:

{
  "sorted": {
    "$$sort": "$.items",
    "by": "##current.date",
    "order": "asc"  // or "desc"
  }
}

Use Case: Sort arrays Search: grep '$$sort' flows/

$$at – Array Element Access

Access array elements by index, including negative indices for reverse access.

Syntax:

"first": "$$at(0):$.array"       // First element
"last": "$$at(-1):$.array"       // Last element (reverse)
"second_last": "$$at(-2):$.array" // Second from end

Object Form:

{
  "external_id": {
    "$$at": -1,
    "from": "$$split(::,2):##current.payee.source.id"
  }
}

Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:45:

{
  "type": "TRANSFORM",
  "id": "external_id",
  "input": "$$at(-1):$$split(::):#current.payee.id"
}

Use Case: Reverse List Access When you need the last element but don’t want to use $$first (which requires non-null check):

{
  "external_id": {
    "$$at": -1,
    "from": "$$split(::,2):##current.payee.source.id"
  }
}

This splits “prefix::id::suffix” by “::” and takes the last element.

Key Differences from $$first:

  • $$at(-1) – Always returns last element (or null if empty)
  • $$first – Returns first non-null value from list of fallbacks
  • Use $$at for positional access, $$first for fallback chains

Negative Indices:

  • -1 = last element
  • -2 = second to last
  • -n = nth from end

Edge Cases:

  • Empty array: Returns null
  • Index out of bounds: Returns null
  • Non-array input: Returns null

Search: grep '$$at' flows/

$$slice – Array Slice

Extract array subrange.

Syntax:

{
  "subset": {
    "$$slice": "$.items",
    "start": 0,
    "end": 10
  }
}

Use Case: Pagination, truncation Search: grep '$$slice' flows/

$$concat – Concatenate Arrays

Combine multiple arrays.

Syntax:

"combined": "$$concat [$.array1, $.array2, $.array3]"

Use Case: Merge arrays Search: grep '$$concat' flows/

$$distinct – Unique Elements

Remove duplicates from array.

Syntax:

"unique": "$$distinct:$.items"

Example from flows/fileupload/validate/items/1.0.3.json:130:

{
  "source": "$$distinct:$._init.items[*].payment.target"
}

Use Case: Deduplicate arrays Search: grep '$$distinct' flows/

$$reverse – Reverse Array

Reverse array order.

Syntax:

"reversed": "$$reverse:$.items"

Use Case: Reverse order Search: grep '$$reverse' flows/

$$lookup – Array Join

Join arrays like SQL JOIN.

Syntax:

{
  "joined": {
    "$$lookup": "$.left_array",
    "using": [
      {
        "with": "$.right_array",
        "as": "match",
        "on": "$$is(=,##current.id):##match.id"
      }
    ],
    "to": {
      "*": "##current",
      "matched_field": "##match.field"
    }
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:728:

{
  "items": {
    "$$lookup": "$._init.items",
    "using": [
      {
        "with": "$.check_for_payments.targets",
        "as": "target",
        "on": "$$is(=,##current.payment.target):##target.source"
      }
    ],
    "to": {
      "*": "##current",
      "payment": {
        "$$if": "##current.payment",
        "then": {
          "*": "##current.payment",
          "target": {
            "*": "##current.payment.target",
            "_currency": "##target.target.currency"
          }
        }
      }
    }
  }
}

Use Case: Join related data Search: grep '$$lookup' flows/

$$entries – Object to Array

Convert object to array of [key, value] pairs.

Syntax:

"pairs": "$$entries:$.object"

Returns: [["key1", "value1"], ["key2", "value2"]]

Example from flows/fileupload/validate/items/1.0.3.json:328:

{
  "$$entries": {
    "$$group": {
      "$$map": "$._init.items",
      "to": {
        "id": "##current.payment.id"
      }
    },
    "by": "##current.id"
  }
}

Use Case: Iterate over object keys Search: grep '$$entries' flows/

$$flatten – Deep Flatten

Flatten nested arrays recursively.

Syntax:

"flat": "$$flatten:$.nested_arrays"

Difference from $$flat:

  • $$flat: One level only
  • $$flatten: Recursive (all levels)

Use Case: Deep nested array flattening Search: grep '$$flatten' flows/

Object Operations (12 operators)

$$object – Create Object

Create object from key-value pairs.

Syntax:

{
  "obj": {
    "$$object": [
      ["key1", "value1"],
      ["key2", "value2"]
    ]
  }
}

Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:51:

{
  "$$object": {
    "$$map": {
      "$$filter": "$$entries:#current.tags",
      "by": "$$test(^#):##current[0]"
    },
    "to": [
      "$$substring(1):##current[0]",
      "##current[1]"
    ]
  }
}

Use Case: Dynamic object creation Search: grep '$$object' flows/

$$entries – Object to Array

See Array Operations section.

$$keys – Object Keys

Extract object keys as array.

Syntax:

"keys": "$$keys:$.object"

Use Case: Get object keys Search: grep '$$keys' flows/

$$values – Object Values

Extract object values as array.

Syntax:

"values": "$$values:$.object"

Use Case: Get object values Search: grep '$$values' flows/

$$merge – Merge Objects

Merge multiple objects.

Syntax:

{
  "merged": {
    "$$merge": [
      "$.object1",
      "$.object2"
    ]
  }
}

Use Case: Combine objects Search: grep '$$merge' flows/

$$get – Safe Object Access

Safely access nested object properties.

Syntax:

"value": "$$get $.object \"nested.path\" \"default\""

Object Form:

{
  "value": {
    "$$get": "$.object",
    "path": "nested.path",
    "default": "fallback_value"
  }
}

Use Case: Safe property access Search: grep '$$get' flows/

$$wrap – Wrap in Object

Wrap value in object with key.

Syntax:

"wrapped": "$$wrap(key):$.value"

Returns: {"key": value}

Example from flows/fileupload/validate/items/1.0.3.json:100:

{
  "$$wrap(.):$$substring(17):##current.message"
}

Chained Example:

{
  "$$wrap(payment.):$$substring(1):$$replace(/,.):##current"
}

Use Case: Dynamic key creation Search: grep '$$wrap' flows/

$$normalize – Normalize Object

Normalize object structure.

Syntax:

{
  "normalized": {
    "$$normalize": "$.object",
    "schema": "$.schema_definition"
  }
}

Use Case: Schema normalization Search: grep '$$normalize' flows/

$$flatten – Flatten Nested Object

Flatten nested object to dot notation.

Syntax:

"flattened": "$$flatten:$.nested_object"

Example:

  • Input: {"a": {"b": {"c": 1}}}
  • Output: {"a.b.c": 1}

Use Case: Flatten object hierarchy Search: grep '$$flatten' flows/

$$unflatten – Unflatten Object

Convert dot notation to nested object.

Syntax:

"nested": "$$unflatten:$.flat_object"

Example:

  • Input: {"a.b.c": 1}
  • Output: {"a": {"b": {"c": 1}}}

Use Case: Restore nested structure Search: grep '$$unflatten' flows/

String Operations (18 operators)

$$join – String Concatenation

Join array elements or strings.

Syntax:

"full_name": "$$join [$.first_name, \" \", $.last_name]"

With Separator:

"csv": "$$join(,):$.array"

Example from flows/fileupload/validate/items/1.0.3.json:292:

{
  "message": {
    "$$join": [
      "Minimun amount for ",
      "##current.target_currency",
      " is ",
      "##current.min_amount"
    ]
  }
}

Use Case: Concatenate strings Search: grep '$$join' flows/

$$split – String Split

Split string into array.

Syntax:

"parts": "$$split(,):$.csv_string"

With Limit:

"parts": "$$split(::,2):$.id"

Example from flows/fileupload/validate/items/1.0.3.json:211:

{
  "target": {
    "$$transform": "$$split(::,2):##current.payment.target.id",
    "to": "##current[1]"
  }
}

Use Case: Parse delimited strings Search: grep '$$split' flows/

$$replace – String Replacement

Replace substring or regex pattern.

Syntax:

"cleaned": "$$replace $.text \"old\" \"new\""

Regex Mode:

"cleaned": "$$replace(/pattern/,replacement):$.text"

Example from flows/fileupload/validate/items/1.0.3.json:105:

{
  "$$wrap(payment.):$$substring(1):$$replace(/,.):##current"
}

Use Case: String substitution Search: grep '$$replace' flows/

$$substring – Substring Extraction

Extract substring.

Syntax:

"sub": "$$substring(0,10):$.text"  // First 10 chars
"from": "$$substring(5):$.text"     // From index 5

Example from flows/fileupload/validate/items/1.0.3.json:94:

{
  "$$is": "$$substring(0,16):##current.message",
  "eq": "Missing property"
}

Use Case: Extract substrings Search: grep '$$substring' flows/

$$upper – Uppercase

Convert to uppercase.

Syntax:

"upper": "$$upper:$.text"

Use Case: Case normalization Search: grep '$$upper' flows/

$$lower – Lowercase

Convert to lowercase.

Syntax:

"lower": "$$lower:$.text"

Use Case: Case normalization Search: grep '$$lower' flows/

$$trim – Trim Whitespace

Remove leading/trailing whitespace.

Syntax:

"trimmed": "$$trim:$.text"

Use Case: Clean input Search: grep '$$trim' flows/

$$template – Text Templates

Advanced string templating with variables.

Syntax:

{
  "message": {
    "$$template": "Hello {{name}}, your balance is {{balance}}",
    "vars": {
      "name": "$.user.name",
      "balance": "$.account.balance"
    }
  }
}

Use Case: Dynamic message generation Search: grep '$$template' flows/

$$test – Regex Test

Test if string matches regex.

Syntax:

"is_email": "$$test $.input \"^[\\w.-]+@[\\w.-]+\\.\\w+$\""

Returns: Boolean

Example from flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json:54:

{
  "by": "$$test(^#):##current[0]"
}

Use Case: Pattern validation Search: grep '$$test' flows/

$$match – Regex Match

Extract regex matches.

Syntax:

{
  "matches": {
    "$$match": "$.text",
    "pattern": "(\\d+)"
  }
}

Returns: Array of matches

Use Case: Pattern extraction Search: grep '$$match' flows/

$$digest – Hash String

Generate hash digest.

Syntax:

{
  "hash": {
    "$$digest": "$.data",
    "algorithm": "SHA256"
  }
}

Use Case: Generate hashes Search: grep '$$digest' flows/

Mathematical Operations (10 operators)

$$math – Mathematical Operations

Perform math operations.

Syntax:

"rounded": "$$math(ROUND,2) $.amount"
"total": "$$math(ADD) [$.subtotal, $.tax]"

Operations:

  • ADD: Sum values
  • SUB: Subtract
  • MUL: Multiply
  • DIV: Divide
  • MOD: Modulo
  • ROUND: Round to decimals
  • ABS: Absolute value
  • CEIL: Round up
  • FLOOR: Round down

Example from flows/fileupload/validate/items/1.0.3.json:249:

{
  "rounded_amount": {
    "$$math": [
      "ROUND",
      "##current.amount"
    ]
  }
}

Use Case: Calculations Search: grep '$$math' flows/

$$numberparse – Parse Number

Parse string to number.

Syntax:

"num": "$$numberparse:$.string_number"

Example from flows/fileupload/validate/items/1.0.3.json:219:

{
  "min_amount": {
    "$$numberparse": {
      "$$first": [
        {"$$jsonpath": "$.payment_validation_config", "path": "..."},
        0
      ]
    }
  }
}

Use Case: Convert strings to numbers Search: grep '$$numberparse' flows/

$$abs – Absolute Value

Get absolute value.

Syntax:

"absolute": "$$abs:$.number"

Use Case: Remove sign Search: grep '$$abs' flows/

$$ceil – Round Up

Round up to integer.

Syntax:

"ceiled": "$$ceil:$.number"

Use Case: Round up Search: grep '$$ceil' flows/

$$floor – Round Down

Round down to integer.

Syntax:

"floored": "$$floor:$.number"

Use Case: Round down Search: grep '$$floor' flows/

$$round – Round Number

Round to nearest integer or decimals.

Syntax:

"rounded": "$$round(2):$.number"  // 2 decimals

Use Case: Rounding Search: grep '$$round' flows/

$$min – Minimum Value

Get minimum value from array.

Syntax:

"minimum": "$$min:$.numbers"

Use Case: Find minimum Search: grep '$$min' flows/

$$max – Maximum Value

Get maximum value from array.

Syntax:

"maximum": "$$max:$.numbers"

Example from flows/fileupload/validate/items/1.0.3.json:688:

{
  "existing_beneficiaries": {
    "$$max": [
      "$.existing_beneficiaries_check.exists.length()",
      "$.existing_beneficiaries_use_lookup_search.items.length()"
    ]
  }
}

Use Case: Find maximum Search: grep '$$max' flows/

Date/Time Operations (8 operators)

$$date – Date Operations

Manipulate and format dates.

Operations:

FORMAT – Format date:

"formatted": "$$date(FORMAT,\"yyyy-MM-dd\") $.timestamp"

ADD – Add duration:

"due_date": "$$date(ADD,DAYS,30) #now"

SUB – Subtract duration:

"past": "$$date(SUB,HOURS,3) #now"

DIFF – Date difference:

"days_diff": "$$date(DIFF,DAYS) [$.start_date, $.end_date]"

EPOCH – Unix timestamp:

"timestamp": "$$date(EPOCH) #now"

Example from flows/fileupload/validate/items/1.0.3.json:372:

{
  "$$is": "$$date(FORMAT,yyyy-MM-dd):##current.date",
  "lt": "$$date(FORMAT,yyyy-MM-dd):$$date(SUB,HOURS,3):#now"
}

Units: YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS

Use Case: Date manipulation Search: grep '$$date' flows/

Type & Validation (12 operators)

$$is – Comparison

Compare values with operators.

Syntax:

"valid": "$$is $.amount > 100"
"equal": "$$is(=,value):$.field"

Operators: =, !=, >, >=, <, <=, in, nin, eq, ne, gt, gte, lt, lte

Use Case: Comparisons Search: grep '$$is' flows/

$$isnull – Null Check

Check if value is null.

Syntax:

"is_null": "$$isnull:$.field"

Returns: Boolean

Example from flows/fileupload/validate/items/1.0.3.json:675:

{
  "by": "$$isnull:##current.beneficiary.entity_type"
}

Use Case: Null validation Search: grep '$$isnull' flows/

$$boolean – Convert to Boolean

Convert value to boolean.

Syntax:

"bool": "$$boolean:$.value"

Use Case: Type conversion Search: grep '$$boolean' flows/

$$length – Get Length

Get length of string or array.

Syntax:

"count": "$.items.length()"

Use Case: Count items Search: grep 'length()' flows/

$$jsonpath – JSONPath Query

Execute JSONPath query.

Syntax:

{
  "result": {
    "$$jsonpath": "$.object",
    "path": "$.nested.path"
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:222:

{
  "$$jsonpath": "$.payment_validation_config",
  "path": "$$wrap(##current.currency,##current.country):.min."
}

Use Case: Complex queries Search: grep '$$jsonpath' flows/

$$jsonvalidate – JSON Schema Validation

Validate JSON against schema.

Syntax:

{
  "validation": {
    "$$jsonvalidate": "$.data",
    "schema": "$.schema_definition"
  }
}

Returns:

{
  "count": 2,
  "errors": [
    {
      "field": "field.path",
      "message": "Error message",
      "uri": "#/path/to/field"
    }
  ],
  "item": {original_data}
}

Example from flows/fileupload/validate/items/1.0.3.json:66:

{
  "$$jsonvalidate": {
    "$$map": "$._init.items[?(@.payment != null)]",
    "to": {
      "index": "##current.index",
      "*": "##current.payment"
    }
  },
  "schema": "$.fetch_schema"
}

Use Case: Schema validation Search: grep '$$jsonvalidate' flows/

Advanced & Meta (11 operators)

$$eval – Evaluate Expression

Evaluate dynamic expression.

Syntax:

{
  "result": {
    "$$eval": "$.dynamic_expression"
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:110:

{
  "$$eval": "$$wrap(,.$ui.errorMessage):$$replace((\\.(\\d+)),[$2],REGEX):$$replace(/,.):$$wrap(\\$.fetch_schema):$$substring(1):##current.path"
}

Use Case: Dynamic expressions Search: grep '$$eval' flows/

$$transform – Nested Transform

Nest transformation logic.

Syntax:

{
  "result": {
    "$$transform": "$.data",
    "to": {
      "field": "##current.value"
    }
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:211:

{
  "target": {
    "$$transform": "$$split(::,2):##current.payment.target.id",
    "to": "##current[1]"
  }
}

Use Case: Complex transformations Search: grep '$$transform' flows/

$$uuid – Generate UUID

Generate UUID v4.

Syntax:

"id": "#uuid"

Use Case: Unique identifiers Search: grep '#uuid' flows/

$$base64 – Base64 Encoding

Encode/decode base64.

Encode:

"encoded": "$$base64(encode):$.data"

Decode:

"decoded": "$$base64(decode):$.encoded_data"

Use Case: Encoding Search: grep '$$base64' flows/

$$hash – Generate Hash

Generate hash of value.

Syntax:

{
  "hash": {
    "$$hash": "$.data",
    "algorithm": "SHA256"
  }
}

Use Case: Hashing Search: grep '$$hash' flows/


Advanced Features

Text Templates with $$template

Advanced string templating with variable interpolation:

{
  "email_body": {
    "$$template": "Dear {{user.name}},\n\nYour payment of {{payment.amount}} {{payment.currency}} was {{status}}.\n\nReference: {{payment.id}}",
    "vars": {
      "user": "$.user",
      "payment": "$.payment",
      "status": "$$lower:$.status"
    }
  }
}

Use Cases:

  • Email/notification templates
  • Dynamic message generation
  • Report formatting

Chained Transformations

Chain multiple operators using : separator:

"result": "$$wrap(payment.):$$substring(1):$$replace(/,.):##current"

Execution Order: Right to left (like function composition)

Example from flows/fileupload/validate/items/1.0.3.json:105:

{
  "type": {
    "$$transform": {
      "$$if": {
        "$$is": "$$substring(0,16):##current.message",
        "eq": "Missing property"
      },
      "then": {
        "$$join": [
          "##current.field",
          "$$wrap(.):$$substring(17):##current.message"
        ]
      },
      "else": "$$substring(1):##current.uri"
    },
    "to": "$$wrap(payment.):$$substring(1):$$replace(/,.):##current"
  }
}

Context Variable Scoping in Nested Operations

When nesting operators, use context to preserve outer scope:

{
  "$$map": "$.outer_array",
  "to": {
    "$$map": "##current.inner_array",
    "context": {
      "##outer": "##current"  // Preserve outer item
    },
    "to": {
      "outer_id": "##outer.id",
      "inner_id": "##current.id"
    }
  }
}

Example from flows/fileupload/validate/items/1.0.3.json:87:

{
  "$$map": "##current.errors",
  "context": {
    "##outer": "##current"
  },
  "to": {
    "type": {...},
    "index": "##outer.item.index"
  }
}

$$eval for Dynamic Expressions

Use $$eval to evaluate expressions stored as strings:

{
  "type": "TRANSFORM",
  "input": {
    "result": {
      "$$eval": "$.user_defined_rule"
    }
  }
}

Use Cases:

  • User-defined validation rules
  • Dynamic field mapping
  • Conditional logic from configuration

Comparison Logic with $$is

Advanced comparison patterns:

Range Checks:

{
  "valid": {
    "$$and": [
      "$$is(>=,0):$.value",
      "$$is(<=,100):$.value"
    ]
  }
}

List Membership:

{
  "is_valid_status": {
    "$$is": "$.status",
    "in": ["APPROVED", "PENDING", "PROCESSING"]
  }
}

Exclusion:

{
  "not_failed": {
    "$$is": "$.status",
    "nin": ["FAILED", "REJECTED", "CANCELLED"]
  }
}

Component Library Reference

Toolbox Components

Excel Operations (toolbox.parse.xlsx):

  • Parse Excel files
  • Extract sheets, cells, rows, columns
  • Cell manipulation: setValue, getValue, getFormula
  • Row/column operations: insert, delete, copy
  • Data transforms: filtering, mapping, aggregation

CSV Operations (toolbox.parse.csv):

  • Parse CSV files
  • Handle delimiters, encoding
  • Data extraction

S3 Operations (toolbox.s3.*):

  • Upload, download files
  • List, delete objects
  • Bucket operations

ISO 20022 Parsing (toolbox.parse.iso20022):

  • Parse ISO 20022 XML messages
  • Payment instructions
  • Financial messaging

Email (toolbox.aws.ses.send):

  • Send emails via AWS SES
  • HTML/text support
  • Attachments

Integration Components (84 components)

HRIS & Payroll:

  • Employee data sync
  • Payroll processing
  • Time & attendance

Data Sync:

  • System integrations
  • Data pipeline components

NetSuite:

  • Financial data sync
  • Journal entries
  • Vendor management

Journal Entries:

  • Accounting integrations
  • Financial posting

Rain Components (13)

Payment Cards:

  • Card issuance
  • Card management
  • Transaction processing

Crypto Wallets:

  • Wallet creation
  • Balance management
  • Transaction operations

Crossmint Components (6)

Blockchain Wallets:

  • Multi-chain wallet support
  • Wallet creation and management

Crypto Transfers:

  • Cross-chain transfers
  • Transaction tracking

Sumsub Components (7)

KYC/AML Verification:

  • Identity verification
  • Document verification
  • Screening and monitoring

Authorization Components (6)

Auth & User Management:

  • Authentication
  • Authorization
  • User operations

Payments Components (2)

Crypto Operations:

  • Payment processing
  • Transaction validation

AI Validation:

  • Intelligent validation
  • Fraud detection

Apps & Payroll (2)

Events:

  • Event handling
  • Webhooks

KYC:

  • Know Your Customer
  • Compliance checks

Finding Components

Search Strategies:

# All components
glob 'components/**/*.json'

# By service
glob 'components/standalone/**/*.json'
glob 'components/toolbox/**/*.json'

# By name
grep '"component_id": "screening"' components/

# By capability
grep 'payment' components/

Common Patterns

Permission Check Pattern

{
  "type": "SEQUENCE",
  "block": "ALL",
  "tasks": [
    {
      "type": "SUB_FLOW",
      "description": "Check permissions",
      "flow_id": "admin.security.permissions.check",
      "flow_version": ">=1.0.0",
      "input": {
        "user_id": "$.user.id",
        "resource": "payment.send"
      },
      "result": "permission_check"
    },
    {
      "type": "SWITCH",
      "result": "switch_result",
      "cases": [
        {
          "condition": "$$is $.permission_check.allowed false",
          "task": {
            "type": "TERMINATE",
            "fail": true,
            "code": "PERMISSION_DENIED"
          }
        }
      ],
      "default": {
        "type": "COMPONENT",
        "description": "Execute protected operation",
        "component_id": "payment.send",
        "input": {...}
      }
    }
  ]
}

Error Handling Pattern

{
  "type": "TRY_CATCH",
  "try": {
    "type": "COMPONENT",
    "component_id": "external.service.call",
    "retries": 2,
    "backoff": 100,
    "multiplier": 3,
    "result": "service_result"
  },
  "catches": [
    {
      "codes": ["VALIDATION_ERROR"],
      "task": {
        "type": "TERMINATE",
        "fail": true,
        "code": "VALIDATION_FAILED",
        "message": "Input validation failed"
      }
    }
  ],
  "default": {
    "type": "TERMINATE",
    "fail": true,
    "code": "UNKNOWN_ERROR",
    "message": "Unexpected error occurred"
  }
}

Parallel Processing Pattern

{
  "type": "FORK",
  "description": "Execute checks in parallel",
  "result": "checks",
  "tasks": [
    {
      "type": "COMPONENT",
      "component_id": "screening.check",
      "input": {"entity_id": "$.entity.id"},
      "result": "screening"
    },
    {
      "type": "COMPONENT",
      "component_id": "compliance.check",
      "input": {"entity_id": "$.entity.id"},
      "result": "compliance"
    }
  ]
}

Retry with Filter Pattern

{
  "type": "SUB_FLOW",
  "flow_id": "payment.process",
  "flow_version": ">=2.0.0",
  "input": {...},
  "fail_retry_filter": ["TEMPORARY_ERROR", "RATE_LIMIT"],
  "result": "process_result"
}

Batch Processing with MAP and $$partition

Pattern: Process large arrays in batches

{
  "type": "SEQUENCE",
  "tasks": [
    {
      "type": "TRANSFORM",
      "id": "create_batches",
      "input": {
        "batches": {
          "$$partition": "$.items",
          "size": 100
        }
      }
    },
    {
      "type": "MAP",
      "id": "process_batches",
      "input": "$.create_batches.batches",
      "task": {
        "type": "COMPONENT",
        "component_id": "process.batch",
        "input": {
          "items": "#current"
        }
      }
    }
  ]
}

Example: flows/standalone/groups/upload/import/v2/beneficiaries/bulk/1.0.2.json

Nested Transformations ($$group → $$entries → $$filter → $$map)

Pattern: Complex data aggregation and transformation

{
  "duplicate_check": {
    "$$flat": {
      "$$map": {
        "$$filter": {
          "$$entries": {
            "$$group": {
              "$$map": "$.items",
              "to": {
                "id": "##current.id",
                "index": "##current.index"
              }
            },
            "by": "##current.id"
          }
        },
        "by": "$$is(>,1):##current[1].length()"
      },
      "to": {
        "$$map": "##current[1]",
        "to": {
          "type": "duplicate",
          "index": "##current.index"
        }
      }
    }
  }
}

Explanation:

  1. $$group: Group items by ID
  2. $$entries: Convert to [key, value] pairs
  3. $$filter: Keep only duplicates (length > 1)
  4. $$map: Transform to error objects
  5. $$flat: Flatten result

Example: flows/fileupload/validate/items/1.0.3.json:326

Fire-and-Forget SUB_FLOW

Pattern: Background processing without waiting

{
  "type": "SEQUENCE",
  "block": "NONE",  // Don't wait for completion
  "tasks": [
    {
      "type": "SUB_FLOW",
      "flow_id": "notifications.send.async",
      "input": {
        "user_id": "$.user.id",
        "message": "$.message"
      }
    }
  ]
}

Use Cases:

  • Notifications
  • Logging
  • Analytics tracking
  • Audit trails

Example: flows/payments/screening/screen/2.0.2.json

Context Variables in Nested $$map

Pattern: Access outer scope in nested iterations

{
  "result": {
    "$$map": "$.outer_array",
    "to": {
      "outer_id": "##current.id",
      "items": {
        "$$map": "##current.inner_array",
        "context": {
          "##outer": "##current"
        },
        "to": {
          "outer_id": "##outer.id",
          "inner_id": "##current.id"
        }
      }
    }
  }
}

Example: flows/fileupload/validate/items/1.0.3.json:343

Pure Memory Flows

Pattern: In-memory processing without persistence

{
  "schema_version": "2",
  "properties": {
    "pure_memory": true
  },
  "task": {
    "type": "TRANSFORM",
    "input": {
      "processed": "$$map $.items (x) => ##current.id"
    }
  }
}

Use Cases:

  • Validation flows
  • Preprocessing
  • Temporary calculations

Example: flows/fileupload/validate/items/1.0.3.json:19

$$lookup for Data Enrichment

Pattern: Join arrays to enrich data

{
  "enriched_items": {
    "$$lookup": "$.items",
    "using": [
      {
        "with": "$.reference_data",
        "as": "ref",
        "on": "$$is(=,##current.id):##ref.id"
      }
    ],
    "to": {
      "*": "##current",
      "additional_field": "##ref.field"
    }
  }
}

Example: flows/fileupload/validate/items/1.0.3.json:728

SEQUENCE Blocking Strategies

ALL – Wait for all tasks:

{
  "type": "SEQUENCE",
  "block": "ALL",
  "tasks": [...]
}

FIRST – Stop after first success:

{
  "type": "SEQUENCE",
  "block": "FIRST",
  "tasks": [
    {"type": "COMPONENT", "component_id": "primary.service"},
    {"type": "COMPONENT", "component_id": "fallback.service"}
  ]
}

NONE – Fire-and-forget:

{
  "type": "SEQUENCE",
  "block": "NONE",
  "tasks": [
    {"type": "SUB_FLOW", "flow_id": "async.operation"}
  ]
}

Troubleshooting Guide

Scope Resolution Errors

Error: “Field not in scope”

Causes:

  1. Missing result field in SWITCH/SEQUENCE/FORK
  2. Referencing field from wrong scope
  3. Typo in field name

Fix:

// Before (broken)
{
  "type": "SWITCH",
  "cases": [...]
}
// Later: $.branch_result.field  // ERROR: Not in scope

// After (fixed)
{
  "type": "SWITCH",
  "result": "branch_result",  // Add this
  "cases": [...]
}

Operator Syntax Errors

Error: “Invalid operator syntax”

Common Mistakes:

  1. $$first nested in other operators:
// Wrong
"items": "$$map $.array (x) => $$first ##current.field1 ##current.field2"

// Right
"items": "$$map $.array (x) => { \"value\": { \"$$first\": [\"##current.field1\", \"##current.field2\"] } }"
  1. Missing escape sequences:
// Wrong
"message": "Cost is $100"  // $ interpreted as JSONPath

// Right
"message": "Cost is \\$100"
  1. Incorrect ##current usage:
// Wrong (outside iterator)
"field": "##current.value"

// Right (inside $$map)
"items": "$$map $.array (x) => ##current.value"

JSONPath Issues

Error: “JSONPath evaluation failed”

Common Issues:

  1. Invalid filter syntax:
// Wrong
"items": "$.array[?(@.status = 'active')]"  // Use == not =

// Right
"items": "$.array[?(@.status == 'active')]"
  1. Missing brackets:
// Wrong
"items": "$.array[*]field"

// Right
"items": "$.array[*].field"

Context Variable Problems

Error: “##current shadowing”

Problem: Nested $$map with same variable name

Fix: Use context to preserve outer scope:

{
  "$$map": "$.outer",
  "to": {
    "$$map": "##current.inner",
    "context": {
      "##outer": "##current"  // Preserve outer
    },
    "to": {
      "outer_id": "##outer.id",
      "inner_id": "##current.id"
    }
  }
}

Performance Issues

Problem: Slow flow execution

Causes:

  1. Large array operations without batching
  2. Sequential operations that could be parallel
  3. Unnecessary transformations

Solutions:

  1. Use $$partition for large arrays:
{
  "batches": {
    "$$partition": "$.large_array",
    "size": 100
  }
}
  1. Use FORK for parallel operations:
{
  "type": "FORK",
  "tasks": [
    {"type": "COMPONENT", "component_id": "service1"},
    {"type": "COMPONENT", "component_id": "service2"}
  ]
}
  1. Avoid deep nesting:
// Instead of deeply nested $$map
// Break into multiple TRANSFORM tasks

Common Anti-Patterns

1. Overusing $$first:

// Anti-pattern
"field": "$$first $.a $.b $.c $.d $.e"

// Better
"field": {
  "$$first": [
    "$.primary_source",
    "$.fallback_source",
    "default_value"
  ]
}

2. Missing error handling:

// Anti-pattern
{
  "type": "COMPONENT",
  "component_id": "external.service"
}

// Better
{
  "type": "TRY_CATCH",
  "try": {
    "type": "COMPONENT",
    "component_id": "external.service"
  },
  "default": {
    "type": "TERMINATE",
    "fail": true,
    "code": "SERVICE_ERROR"
  }
}

3. Not using result field:

// Anti-pattern
{
  "type": "SWITCH",
  "cases": [...]
}
// Later: $.branch_result  // ERROR

// Better
{
  "type": "SWITCH",
  "result": "branch_result",
  "cases": [...]
}

Validation Rules

Deployment Readiness Checklist

  • Flow ID matches directory structure (entity.domain.action)
  • Version is semantic (1.0.0, 1.2.3, etc.)
  • Meta labels include “deployable” and “ci/cd”
  • Schema version is “2”
  • All JSONPath references are in scope
  • All component references exist in components/
  • All sub-flow references exist in flows/
  • Expression operators use correct syntax
  • SWITCH/SEQUENCE tasks with subsequent references have result field
  • Error handling with TRY_CATCH around risky operations

Common Scope Errors

  1. Missing result field: SWITCH/SEQUENCE without result can’t be referenced later
  2. $$first nested: Must be at root level, not inside other operators
  3. Wrong JSONPath: Referencing $.field that doesn’t exist in scope
  4. Compile vs Runtime: Some validations happen at flow load, others at execution

Schema Validation

Input Schema:

{
  "schema": {
    "input": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "field": {"type": "string"}
      },
      "required": ["field"]
    }
  }
}

Output Schema:

{
  "schema": {
    "output": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "result": {"type": "string"}
      }
    }
  }
}

Best Practices

Security

  • Always check permissions: Use security sub-flows at flow start
  • Validate inputs: Use TRANSFORM to validate and sanitize
  • Handle sensitive data: Never log passwords, tokens, or PII
  • Use sensitive_data field: Mark sensitive COMPONENT/SUB_FLOW tasks

Error Handling

  • Wrap risky operations: Use TRY_CATCH around COMPONENT and SUB_FLOW
  • Provide meaningful codes: Use specific error codes for catches
  • Always have default: Include default catch for unexpected errors
  • Use fail_retry_filter: Retry only on specific error codes

Observability

  • Tag flows: Use TAGS at start for tracking
  • Report status: Use STATUS for long-running operations
  • Log important events: Use components for logging/auditing
  • Use descriptive IDs: Name tasks clearly for debugging

Performance

  • Use FORK for independent operations: Parallel execution where possible
  • Configure retries appropriately: retries: 2, backoff: 100, multiplier: 3
  • Avoid unnecessary transformations: Keep TRANSFORM operations simple
  • Use $$partition: Batch large arrays for processing
  • Pure memory for validation: Set pure_memory: true for non-persistent flows

Maintainability

  • Use sub-flows: Extract reusable logic
  • Clear descriptions: Every task should have descriptive text
  • Follow naming conventions: Use descriptive result field names
  • Version constraints: Use semantic versioning for sub-flows (>=1.0.0 <2.0.0)
  • Document complex logic: Add comments in descriptions

Testing

  • Test edge cases: Handle null values, empty arrays, missing fields
  • Test error paths: Verify TRY_CATCH behaviors
  • Integration tests: Test with actual components in flow-tests/
  • Validate schemas: Ensure input/output schemas are correct

Search Strategies

Finding Components

# All components
glob 'components/**/*.json'

# Specific service
glob 'components/standalone/features/**/*.json'

# By name pattern
grep '"component_id": "screening"' components/

Finding Similar Flows

# By domain
glob 'flows/payment/**/*.json'

# By task type
grep '"type": "FORK"' flows/

# By component usage
grep '"component_id": "toolbox.parse.xlsx"' flows/

# By error handling
grep 'fail_retry_filter' flows/

Finding Patterns

# Permission checks
grep 'admin.security.permissions' flows/

# Retry patterns
grep -A 5 'fail_retry_filter' flows/

# Parallel execution
grep -A 10 '"type": "FORK"' flows/

# Error handling
grep -B 2 -A 10 '"type": "TRY_CATCH"' flows/

# Batch processing
grep '"type": "MAP"' flows/

# Pure memory flows
grep 'pure_memory' flows/

Quick Reference Commands

Validation

# Validate flows against all environments
cd cicd && python3 -m validate_flows_pr

# Validate flow resources
./gradlew validateFlowResources

# Run flow tests
./gradlew :flow-tests:test

Deployment

# Prepare deployment payloads
cd cicd && python3 -m prepare_data

# Deploy to environment
export MATRIX_ENVIRONMENTS=integration
cd cicd && python3 -m deploy

Testing

# Run all tests
./gradlew test

# Run specific test class
./gradlew :app:test --tests "CommandHandlerTaskTest"

# Run integration tests
./gradlew :flow-tests:test

How to Help Users

When User Says: “Create a flow that…”

  1. Ask clarifying questions: inputs, outputs, validations, error handling needs
  2. Search for similar flows: Use Glob/Grep to find patterns
  3. Identify components needed: Search components/ directory
  4. Suggest flow structure: Recommend task types and composition
  5. Generate complete JSON: Use schema v2 format with proper structure
  6. Validate the flow: Check scope, expressions, references
  7. Write to correct path: flows/{domain}/{subdomain}/{action}/{version}.json
  8. Suggest tests: Recommend test scenarios

When User Says: “Validate this flow”

  1. Read the flow file (if path provided) or parse JSON
  2. Check schema structure: id, version, meta, properties, task
  3. Validate JSONPath references: All $.references must be in scope
  4. Check expressions: Operator syntax, $$first placement, composition
  5. Verify references: Components and sub-flows exist
  6. Check deployment readiness: Meta labels, directory structure, version format
  7. Report specific issues: Line by line with fixes
  8. Offer to apply fixes: Use Edit tool if needed

When User Says: “Find flows that…”

  1. Use Glob for file patterns: glob 'flows/**/payment/*.json'
  2. Use Grep for content: grep '"component_id": "screening"' flows/
  3. Read matching files: Show relevant excerpts
  4. Explain patterns: What makes them work
  5. Suggest similar approaches: How to adapt for user’s needs

When User Says: “Explain this flow”

  1. Read the flow file
  2. Parse task hierarchy: Show structure with indentation
  3. Explain each task: What it does, why it’s there
  4. Identify integrations: Components, sub-flows, services
  5. Show data flow: How data transforms through tasks
  6. Note best practices: What’s done well
  7. Suggest improvements: If any issues found

When User Says: “Debug this error”

  1. Analyze error message: Identify error type (scope, syntax, reference)
  2. Reference validation model: Compile-time vs runtime
  3. Find root cause: Missing result field, wrong JSONPath, etc.
  4. Suggest specific fix: Code snippet with correction
  5. Explain why it works: Scope resolution, operator rules
  6. Validate fix: Confirm it solves the issue
  7. Offer to apply: Use Edit tool if user agrees

Response Format

When helping users, structure your responses as:

  1. Understanding: Confirm what they need
  2. Search: Show what you’re searching for and results
  3. Analysis: Explain findings or approach
  4. Solution: Provide code/fixes with explanations
  5. Validation: Verify the solution works
  6. Next Steps: Suggest follow-up actions

Always cite specific files with line numbers (file_path:line_number) when referencing code.


Remember

  • Search first: Always look for existing patterns before creating new ones
  • Validate thoroughly: Check scope, expressions, references, deployment readiness
  • Explain clearly: Users are learning – teach as you help
  • Be specific: Provide exact JSONPath, component IDs, file paths
  • Test suggestions: Reference existing working examples
  • Follow conventions: Maintain consistency with existing flows

You are the expert. Be confident, thorough, and helpful. Use your tools to search, validate, and create flows that follow best practices and work correctly on first deployment.


Version 2.0.0 – Complete Operator Reference

What’s New

✨ 73 new operators: $$group, $$partition, $$lookup, $$at, $$entries, $$template, $$eval, $$switch, and 65 more ✨ 3 new task types: MAP (batch processing), AWAIT (async ops), EVALUATE (dynamic expressions) ✨ 5 new sections: Quick Reference, Core Concepts, Advanced Features, Component Library, Troubleshooting Guide ✨ 5 new patterns: Batch processing, nested transformations, fire-and-forget, context variables, pure memory flows ✨ 103 components documented: Complete component library across 8 services

What Changed

📝 Expression Operators reorganized into 8 categories (was flat list) 📝 All examples reference real production flows with file paths 📝 Context variables deeply explained (##current vs #now vs #env.*) 📝 Special focus on $$at for reverse list access (vs $$first for fallbacks)

Backward Compatibility

✅ All v1.0.0 content preserved ✅ No breaking changes to syntax or behavior ✅ Existing skills continue to work ✅ Team members can continue using v1.0.0 if needed