Predicates
Skip Steps based on Flow state with a Lua, Ale, or JSONPath predicate (condition script). Includes match predicates for filtering individual upstream values and dependency pruning after a skipped Step.
Skip Conditions
A Step can include a Predicate, which is a condition script. If it evaluates to false when the Step’s inputs are ready, the Step is skipped and no service call is made:
{
"id": "send-premium-discount",
"type": "sync",
"predicate": {
"language": "lua",
"script": "return customer_tier == \"premium\""
}
}
A skipped Step produces no outputs. Downstream Steps that depend on those outputs will fail if they have no other way to get them.
Predicate Languages
JSONPath (jpath)
jpath is Argyll’s language identifier for JSONPath-style expressions. It has Argyll-specific behavior rather than claiming full compatibility with every JSONPath implementation. The Predicate is true when the query matches at least one value.
$.customer.tier == "premium"
$.amount > 100
$.status != "cancelled"
Lua
Use Lua for conditions involving multiple Attributes or more complex logic:
return amount > 1000 and status == "approved"
Ale
Argyll’s native scripting language. Purely functional, safe for Predicates:
(and (> amount 1000) (eq status "approved"))
Errors vs Skips
A Predicate that evaluates to false skips the Step. A Predicate that throws a runtime error fails the Step. Predicates should be simple boolean expressions over known Attributes. If a Predicate can throw an error, it’s a sign the logic belongs elsewhere.
Dependency Pruning
When a Step is skipped, upstream work that existed only for that Step is pruned, meaning removed because it is no longer needed. This avoids executing unnecessary work.
Interaction with For Each
When a Step has both a Predicate and for_each, the Predicate is evaluated before initial Work Item scheduling and again before each pending or retried Work Item starts. If the Predicate is false, that work does not run.
Routing
Use Predicates to route work conditionally. Different Steps with different Predicates handle different paths:
payment_method: ?"] Check1{"payment_method
== credit_card?"} Check2{"payment_method
== bank_transfer?"} CC["charge-card"] Bank["initiate-transfer"] Confirm["confirm-payment"] Init --> Check1 Init --> Check2 Check1 -->|true| CC Check2 -->|true| Bank CC --> Confirm Bank --> Confirm style CC fill:#c8e6c9 style Bank fill:#c8e6c9
Match Predicates on Required Inputs
A required input can declare a match script that filters upstream values before collection. Each candidate value is evaluated individually, and only values that pass are collected. If no values pass once all providers finish, the Step is skipped without demanding its other required inputs.
{
"attributes": {
"payment_result": {
"role": "required",
"required": {
"match": {
"language": "jpath",
"script": "$.status == \"approved\""
}
}
}
}
}
The match script receives one candidate at a time. For Ale and Lua the candidate is available as value; for Argyll JSONPath (jpath) it is evaluated as the document.