Skip to main content

Overview

Tracecat expressions let you build values from trigger data, action results, secrets, variables, and functions. Expressions use ${{ ... }}.

Where expressions are used

You can use expressions in:
  • Action inputs
  • run_if
  • for_each
  • Output schema
Use var.<name> in action inputs for actions that run with for_each. The workflow-level environment field takes a literal string. An action-level environment override may be a single standalone ${{ ... }} expression, evaluated at run time; anything else is used literally.

Expression contexts

TRIGGER

The payload that started the run; append a JSONPath to read a field. Bare ${{ TRIGGER }} passes the whole payload through; no other context works without a suffix.

ACTIONS

Results of upstream actions, referenced as ACTIONS.<ref> plus a JSONPath. Each action exposes result, result_typename, error, and error_typename.

SECRETS

Secret values, referenced as exactly SECRETS.<name>.<KEY>. Both segments must be plain identifiers; a hyphenated secret name is unreachable from expressions.

VARS

Workspace variables, referenced as VARS.<name>.<key> with at most one key segment after the variable name.

ENV

Workflow metadata such as execution IDs, the trigger type, and the Workflow environment, referenced as ENV plus a JSONPath.

var

The loop variable that for_each binds on each iteration, referenced as var.<name> plus a JSONPath.

FN

Function calls, written as FN.<name>(...), always with parentheses and only positional arguments. Append .map to apply a function to every item of a list.

inputs

Available only inside YAML template actions: reads the values passed to the template’s Input schema as inputs.<field>.

steps

Available only inside YAML template actions: reads the result of an earlier template step at steps.<ref>.result.

Syntax

Literals

  • String literals such as "high" and 'prod'
  • Numeric literals such as 1 and 3.14
  • Boolean literals such as True and False
  • Null literals such as None
  • List literals such as ["a", "b"]
  • Object literals with string keys such as {"severity": "high"}

Operators

  • Logical operators: ||, &&, and not. Write || and &&, not Python-style or / and or SQL-style OR / AND.
  • Comparison operators: ==, !=, <, <=, >, >=
  • Membership operators: in and not in, such as ${{ TRIGGER.severity in ["high", "critical"] }}
  • Identity operators: is and is not, such as ${{ TRIGGER.title is None }}
  • Arithmetic operators: +, -, *, /, %, and unary -x / +x
  • Ternary expressions such as ${{ "p1" if TRIGGER.severity == "high" else "p3" }}

Evaluation rules

  • || and && evaluate both sides; only the ternary short-circuits. See Common mistakes.
  • A function result supports operators and indexing but not .field access: FN.now().hour fails to parse. JSONPath chaining such as TRIGGER.items[0].id works as usual.

Type casts

The four casts are int, float, str, and bool, written as a call or as a trailing cast on the whole expression:
Parse datetime strings with FN.to_datetime; there is no datetime cast.

Examples

Conditional execution:
Iteration:

FAQ

When a field does not exist, the expression resolves to None without raising an error. Use run_if with a != None check to skip downstream actions when the data is missing, or use a ternary to supply a fallback value.