> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/guardrails/llms.txt.
> For full documentation content, see https://docs.nvidia.com/nemo/guardrails/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/guardrails/_mcp/server.

# Flow control

> Flow control is an essential tool in all programming languages, and Colang supports this as well. It enables branching and repetition of interaction patterns in a single flow.

<a id="flow-control" />

Flow control is an essential tool in all programming languages, and Colang supports this as well. It enables branching and repetition of interaction patterns in a single flow.

## Conditional Branching (`if/elif/else`)

Syntax definition of conditional branching:

```text
if <condition1>
    <interaction pattern sequence 1>
[elif <condition2>
    <interaction pattern sequence 2>]
.
.
.
[else
    <interaction pattern else sequence>]
```

The conditional branching is a well known concept and works identical to Python:

**control\_flow\_tools/conditional\_branching/main.co**

```text
flow main
    $number_of_users = 1
    if $number_of_users == 0
        await user became present
    elif $number_of_users > 1
        bot say "I am sorry, I can only interact with a single user!"
    else
        bot say "Welcome! Nice to meet you!"
    match RestartEvent()
```

In this example, the bot's reaction depends on the state of the variable `$number_of_users` that would contain the number of available users.

<a id="flow-control-event-branching" />

## Event Branching (`when/or when/else`)

Event branching is a new Colang-based concept that enables a branching based on expected events.

Syntax definition of event-based branching:

```text
when <MixedGroup1>
    <interaction pattern sequence 1>
[or when <MixedGroup2>
    <interaction pattern sequence 2>]
.
.
.
[else
    <interaction pattern else sequence>]
```

* The `<MixedGroup>` stands for a mixed grouping of flows, actions and events
* All actions and flows in the `when/or when` statements will be started concurrently
* If neither the `or when` nor the `else` statement is used, the `when` construct could be replaced with either just an `await` or `match` statement

With the concurrent pattern matching mechanism, we have already seen one way to design a branching interaction pattern based on the user's input:

**control\_flow\_tools/concurrent\_patterns/main.co**

```text
flow main
    bot say "How are you?"
    bot react to user feeling good or bot react to user feeling bad

flow bot react to user feeling good
    user said "Good" or user said "Great"
    bot say "Great"

flow bot react to user feeling bad
    user said "Bad" or user said "Terrible"
    bot say "Sorry to hear"
```

Depending on the user's answer we will get a different bot reaction. Although this concurrent flow mechanism is very powerful, it is sometimes better to have everything in a single flow with the help of the `when` construct:

**control\_flow\_tools/event\_branching/main.co**

```text
flow main
    bot say "How are you?"
    bot react to user wellbeing

flow bot react to user wellbeing
    when user said "Good" or user said "Great"
        bot say "Great"
    or when user said "Bad" or user said "Terrible"
        bot say "Sorry to hear"
```

The number of cases can easily be extended by adding more `or when` statements. The `else` statement will only trigger if all of the `when/or when` statements have failed.

From the definition we see that `when/or when` statements support mixed groups that can contain events, actions, and flows. For events, this works like a `match` statement, whereas for actions and flows, it behaves like an `await` statement. Therefore, actions and flows will be started and then matched with their `Finished` event. Note that all flows and actions will be started concurrently in the different `when/or when` statements and stopped as soon as the first case succeeds.

All started flows and actions in all the `when/or when` statements will be stopped as soon as one of the cases succeeded.

We can also use this construct to easily create a branching for a flow that either finishes or fails:

**control\_flow\_tools/catch\_failing\_flow/main.co**

```text
flow main
    start pattern a
    when pattern b
        bot say "Pattern b has finished"
    else
        bot say "Pattern b has failed"

flow pattern a
    user said "Hello"
    bot say "Hello"

flow pattern b
    user said something
    bot say "Hi"
```

Due to the event generation conflict resolution, `'pattern b'` will fail for the user input "Hello", but successfully finish for the user input "Hi":

```text
> Hello

Hello

Pattern b has failed

> Hi

Hi

Pattern b has finished
```

It is considered "bad design" when used with action-like flows that start with an action:

```text
flow bot greet then comment
    when bot say "Hi there!"
        bot say "I am done talking first"
    or when bot gesture "Wave with one hand"
        bot say "I am done gesturing first"

flow bot say $text
    await UtteranceBotAction(script=$text)

flow bot gesture $gesture
    await GestureBotAction(gesture=$gesture)
```

This example will not work correctly because only one of the two actions will be started due to the action conflict between `UtteranceBotAction` and `GestureBotAction`. Note that such cases can be easily detected when following a proper flow [naming convention](defining-flows#flow-naming-conventions) since `when bot say "Hi there!"` is grammatically incorrect. The example above would need to be implemented like this:

```text
flow bot greet then comment
    start bot say "Hi there!" as $action_1_ref
        and bot gesture "Wave with one hand" as $action_2_ref
    when $action_1_ref.Finished()
        bot say "I am done talking first"
    or when $action_2_ref.Finished()
        bot say "I am done gesturing first"
```

The `when/or when/else` branching should only be used with intent-like flows.

## Loop (`while`)

Syntax definition of a loop:

```text
while <condition>
    <interaction pattern sequence>
```

In this example, the bot will count from one to ten:

**control\_flow\_tools/loop/main.co**

```text
flow main
    bot count to 10

flow bot count to $number
    $current_number = 1
    while $current_number < $number
        bot say "{$current_number}"
        $current_number = $current_number + 1
```

In order to abort the loop early or to skip the rest of the current loop iteration, the keywords `break` and `continue` can be used, respectively:

```text
flow bot count to $number
    $current_number = 0 # Initialized it with 0
    while True # Endless loop
        bot say "{$current_number}"
        $current_number = $current_number + 1
        if $current_number == 0
            continue # Skip the number 0
        if $current_number > $number
            break # Break out of loop when target number was reached
```

<a id="flow-control-return-abort" />

## Finish or abort a flow (`return/abort`)

Flows can be finished or failed at any point from within the flow using the keywords `return` and `abort`, respectively:

```text
flow main
    user greeted then expressed feeling unwell

flow user greeted then expressed feeling unwell
    match user greeted
    when user expressed feeling unwell
        return
    or when user said something
        abort
    # We never reach this, except if both cases fail
```

Additionally, `return` takes an optional value such that you can use a flow like a common function:

```text
flow main
    $result = await multiply 3 4
    bot say "{$result}"

flow multiply $number_1 $number_2
    return $number_1 * $number_2
```

If you do not provide a return value, `None` is passed by default.

When assigning the return value of a flow to a variable `await` is not optional before the flow name.

## No-op operation (`pass`)

Sometimes, it is useful to have a no-operation keyword `pass`, for example as a placeholder to make the syntax valid:

```text
flow main
    user greeted then expressed feeling unwell

flow user greeted then expressed feeling unwell
    match user greeted
    when user expressed feeling unwell
        pass # Just continue with the flow
    or when user said something
        abort
    # The flow will successfully finish here
```