> ## Documentation Index
> Fetch the complete documentation index at: https://rasa.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Conditions in Flows

> Conditions

## Conditions

Conditions are used in flows in three different places:

* In [flow guards](/docs/reference/primitives/starting-flows#flow-guards) to determine whether a flow can be started.
* In the [next](/docs/reference/primitives/flows#steps) field of a flow step to choose between branches of your business logic.
* In the `rejections` field of a `collect` step to [validate slot values](/docs/reference/primitives/flow-steps#slot-validation).

### Syntax

Conditions in flows are written using natural language that can include
logical operators, conditional operators and other constructs. They are evaluated
with the [pypred](https://github.com/armon/pypred) library.

These conditions support the following operators,

* `not`: Negates a condition.
* `and`: Combines two conditions with logical AND.
* `or`: Combines two conditions with logical OR.
* `>`: Greater than.
* `>=`: Greater than or equal to.
* `<`: Less than.
* `<=`: Less than or equal to.
* `=`: Equal to.
* `!=`: Not equal to.
* `is`: Checks for identity.
* `is not`: Checks for non-identity.
* `contains`: Subset operator that checks if a set contains a value
* `matches`: Uses regular expressions to match strings.

#### Parentheses

Use parentheses to group expressions and control the order of evaluation. For example:

```yaml theme={null}
- collect: age
  next:
    - if: slots.age < 18
      then: under_18_step
    - if: (slots.age > 18 and (consent = "yes" or consent = "y"))
      then: consent_accept
    - else: consent_decline
```

#### Subset Operator

Subset operator `contains` can be used in the format `SET contains VALUE`
where `SET` is the set of possible values and `VALUE` being the name of slot.
For example:

```yaml theme={null}
- collect: emergency
  next:
    - if: "{'WARN' 'ERR' 'CRIT'} contains slots.error_level"
      then: handoff
    - else: everything_okay
```

`contains` operator can also be used to identify substrings when used as
`slots.product contains "Rasa"` however this check is case-sensitive.

#### Constants

* String literals: Enclose in single or double quotes (`'example'` or `"example"`).
* Numeric literals: Numbers without quotes (`42`).
* Constants: `true`, `false`, `undefined`, `null`, `empty`

#### Regular Expressions

When using the `matches` operator, you can include regular expression modifiers.
The regex modifier should be enclosed in quotes. For example, this flow step checks if
the `zipcode` slot contains a United States zip code :

```yaml theme={null}
- collect: zipcode
  description: ask zipcode and check if its a zip code
  next:
    - if: slots.zipcode matches "\d{5}(-\d{4})?"
      then: ask_payment
    - else: wrong_zipcode
```

A case-insensitive substring comparison can be made with the condition
`product matches "(?i).*rasa.*"` which checks for the substring `rasa` within
the variable `product`.

#### Empty Values

If you want to check if a boolean slot is not set, you need to use the syntax `<boolean-slot> is null`.

To check if a text slot is not set or empty, use the syntax `not <text-slot>`.

#### Examples

Here are some examples of conditions that demonstrate the use of different constructs.

```yaml theme={null}
# Simple conditions
age > 18
name is "Alice"
name is empty
status = "active"
status is not null

# Combining Conditions
age > 21 and gender = "female"
category = "electronics" or category = "computers"
status = "active" and (priority = 1 or priority = 2)
status = empty or status is null
description matches "/error \d{3}/i" and (severity = "high" or source contains "server")
```

## Namespaces

Namespaces are used to access different types of data in predicates used in
[branching conditions](/docs/reference/primitives/flow-steps#next-property), [slot validation](/docs/reference/primitives/flow-steps#slot-validation),
and [flow guards](/docs/reference/primitives/starting-flows#flow-guards).
There are two available namespaces: `slots` and `context`. The `slots` namespace
is used to access slot values, while the `context` namespace is used to access
the current dialogue frame properties.

### Slots

The `slots` namespace is used to access slot values. The slot name must be
prefixed with `slots.` to be accessible in the condition. For example:

```yaml theme={null}
- id: some_question
  collect: age
  next:
    - if: slots.age < 18
      then: under_18_step
    - else: over_18_step
```

Make sure to have the slot defined in the [domain](/docs/reference/config/domain).
If the slot is not defined in the domain or the slot is not prefixed with `slots.` namespace,
the validation that runs during training will fail with an appropriate error.

### Context

The `context` namespace is used to access the properties of the current [dialogue frame](/docs/reference/primitives/conditions#dialogue-frames).
The property must be prefixed with `context.` to be accessible in
the predicate. For example:

```yaml theme={null}
  pattern_completed:
    description:  a flow has been completed and there is nothing else to be done
    steps:
      - noop: true
        next:
          - if: context.previous_flow_name != "greeting"
            then:
              - action: utter_what_can_help_with
                next: END
          - else: stop
      - id: stop
        action: action_stop
```

You can also use jinja templating to access the context namespace. For example:

```yaml theme={null}
  pattern_completed:
    description:  a flow has been completed and there is nothing else to be done
    steps:
      - noop: true
        next:
          - if: "{{context.previous_flow_name}}" != "greeting"
            then:
              - action: utter_what_can_help_with
                next: END
          - else: stop
      - id: stop
        action: action_stop
```

#### Dialogue Frames

The dialogue manager organizes the advancement of flows (both user defined and built-in)
in a dialogue frame stack. The dialogue frame stack represents a LIFO (Last-In-First-Out) stack of dialogue frames.
Different types of dialogue frames are mapped to built-in conversational patterns that enable
[conversation repair](/docs/learn/concepts/conversation-patterns).

Each dialogue frame has a `flow_id` and `step_id` property. The `flow_id` is the id of the current
flow and the `step_id` is the id of the current step in the flow.

The following dialogue frames types are available:

1. [cancel](/docs/reference/primitives/conditions#cancel): handles flow cancellation
2. [chitchat](/docs/reference/primitives/conditions#chitchat): handles chitchat
3. [clarify](/docs/reference/primitives/conditions#clarify): handles clarification
4. [collect information](/docs/reference/primitives/conditions#collect-information): handles information collection
5. [completion](/docs/reference/primitives/conditions#completion): handles flow completion
6. [continue interrupted](/docs/reference/primitives/conditions#continue-interrupted): handles continuation of interrupted flows
7. [correction](/docs/reference/primitives/conditions#correction): handles correction
8. [internal error](/docs/reference/primitives/conditions#internal-error): handles internal errors
9. [search](/docs/reference/primitives/conditions#knowledge-search): handles knowledge search
10. [skip question](/docs/reference/primitives/conditions#skip-question): handles skipping of information collection
11. [code change](/docs/reference/primitives/conditions#code-change): cleans the stack after an assistant update
12. [can not handle](/docs/reference/primitives/conditions#can-not-handle): handles situations where the assistant cannot handle
13. [human handoff](/docs/reference/primitives/conditions#human-handoff): handles handoff to human
14. [validate slot](/docs/reference/primitives/conditions#validate-slot): handles real-time slot validations that are strictly independent of business logic
15. [customer satisfaction](/docs/reference/primitives/conditions#customer-satisfaction): handles customer satisfaction feedback collection at the end of a conversation

##### Cancel

The `flow_id` is `pattern_cancel_flow`. The `step_id` is `START`.
In addition, the following properties are available:

* `canceled_name`: the name of the flow that should be canceled
* `canceled_frames`: the list of stack frames that should be canceled

##### Chitchat

The `flow_id` is `pattern_chitchat`. The `step_id` is `START`.

##### Clarify

The `flow_id` is `pattern_clarify`. The `step_id` is `START`.
In addition, the following properties are available:

* `names`: the list of names of the flows that the user can choose from
* `clarification_options`: the options that the user can choose from as a string

##### Collect Information

The `flow_id` is `pattern_collect_information`. The `step_id` is `START`.
In addition, the following properties are available:

* `collect`: the name of the slot that should be filled
* `utter`: the response that should be executed to ask the user for information
* `collect_action`: the action that should be executed to ask the user for information
* `rejections`: the optional list of validation checks that should be executed if the user provides invalid information

Note that if you are using the `context.collect` property in your flow, you must write this in jinja templating style
and prefix it with the `slots.` namespace. This is because `context.collect` corresponds to the slot name, and every slot must
be preceded by the `slots.` namespace.

For example:

```yaml theme={null}
  pattern_collect_information:
    name: "pattern_collect_information"
    description:  the assistant is collecting information from the user
    steps:
      - id: check
        next:
          - if: "slots.{{context.collect}} is not null"
            then:
              - action: utter_ask_age
                next: listen
          - else: END
      - id: listen
        action: action_listen
```

##### Completion

The `flow_id` is `pattern_completed`. The `step_id` is `START`.
In addition, the following properties are available:

* `previous_flow_name`: the name of the flow that has been completed

##### Continue Interrupted

The `flow_id` is `pattern_continue_interrupted`. The `step_id` is `START`.
In addition, the following properties are available:

* `previous_flow_name`: the name of the flow that was interrupted
* `interrupted_flow_names`: names of the previous flows that were interrupted
* `interrupted_flow_ids`: ids of the previous flows that were interrupted
* `interrupted_flow_options`: options of interrupted flows that the user can choose from as a string
* `multiple_flows_interrupted`: boolean indicating whether multiple flows were interrupted

##### Correction

The `flow_id` is `pattern_correction`. The `step_id` is `START`.
In addition, the following properties are available:

* `is_reset_only`: indicates if the correction is only a reset of the flow
* `corrected_slots`: slot key-value pairs that should be corrected
* `reset_flow_id`: the ID of the flow to reset to, defaults to `None`
* `reset_step_id`: the ID of the step to reset to, defaults to `None`

##### Internal Error

The `flow_id` is `pattern_internal_error`. The `step_id` is `START`.
In addition, the following properties are available:

* `error_type`: string that indicates the type of error. Common values:
  * `rasa_internal_error_default` — generic internal errors (including agent and MCP tool failures unless a more specific type applies)
  * `rasa_internal_error_user_input_too_long` — user input exceeded the configured character limit
  * `rasa_internal_error_user_input_empty` — blank user message
* `info`: dict with structured failure context. Contents vary by call site; many paths push an empty dict. When a ReAct/A2A sub agent or MCP tool call fails, `info` includes fields you can use in flow predicates and responses. See the [`context.info` field reference](/docs/reference/primitives/patterns#handling-agent-and-mcp-tool-failures) for available keys and a customization example.

##### Knowledge Search

The `flow_id` is `pattern_search`. The `step_id` is `START`.

##### Skip Question

The `flow_id` is `pattern_skip_question`. The `step_id` is `START`.

##### Code Change

The `flow_id` is `pattern_code_change`. The `step_id` is `START`.

##### Can Not Handle

The `flow_id` is `pattern_cannot_handle`. The `step_id` is `START`.
In addition, the following properties are available:

* `reason`: string indicates the reason why the assistant cannot handle

##### Human Handoff

The `flow_id` is `pattern_human_handoff`. The `step_id` is `START`.

##### Validate Slot

<Info>
  **New in 3.12**

  You can now enable [real-time slot validation](/docs/reference/primitives/slots#real-time-slot-validation) in Rasa Pro 3.12.0.
</Info>

The `flow_id` is `pattern_validate_slot`. The `step_id` is `START`.
In addition, the following properties are available:

* `validate`: the name of the slot that should be validated
* `refill_utter`: the response that should be executed to ask the user to refill the invalid slot
* `refill_action`: the action that should be executed to ask the user to refill the invalid slot
* `rejections`: the list of validation checks that should be executed if the user provides information for a slot that requires validation

Note that if you are using the `context.validate` property in your flow, you must write this in jinja templating style
and prefix it with the `slots.` namespace. This is because `context.validate` corresponds to the slot name, and every slot must
be preceded by the `slots.` namespace.

For example:

```yaml theme={null}
  pattern_validate_slot:
    name: "pattern_validate_slot"
    description:  the assistant is validating information received from the user
    steps:
      - id: check
        next:
          - if: "slots.{{context.validate}} is not null"
            then:
              - action: utter_refill_age
                next: listen
          - else: END
      - id: listen
        action: action_listen
```

##### Customer Satisfaction

<Info>
  **New in 3.16**

  You can now enable customer satisfaction feedback collection in Rasa Pro 3.16.0.
</Info>

The `flow_id` is `pattern_customer_satisfaction`. This pattern is triggered from `pattern_completed` via a `link` step when the user opts to end the conversation.


## Related topics

- [Responses](/docs/reference/primitives/responses.md)
- [Rasa Pro Change Log](/docs/reference/changelogs/rasa-pro-changelog.md)
- [Rasa Pro Version Migration Guide](/docs/reference/changelogs/rasa-pro-migration-guide.md)
- [Flow Steps](/docs/reference/primitives/flow-steps.md)
- [How to Trigger Flows](/docs/studio/build/flow-building/trigger-flows.md)
