---
title: "Step decisions"
description: "Execute returns a StepDecision. The decision moves to next Steps,"
canonical_url: "https://docs.superdurable.io/reference/java/step-decisions/"
source: "docs/reference/java/step-decisions.mdx"
locale: "en"
---

# Step decisions

**Execute** returns a **StepDecision**. The decision moves to next Steps,
closes the Flow, or stops this branch. It can also cancel other Steps.

<a id="gotomulti"></a>

## Multiple next Steps

**GoTo** starts one next Step. **GoToMany** starts multiple next Steps. Each
Step movement has its own input and can also have its own
[Step options](https://docs.superdurable.io/reference/java/step-options.md#stepoptions-override-per-stepexecution).

```java
return StepDecision.goToMany(
        StepMovement.of(CarrierA.class, quoteA),
        StepMovement.of(CarrierB.class, quoteB),
        StepMovement.of(Winner.class, winnerQuote));
```

Example: [examples/java/src/main/java/io/superdurable/dex/primitives/stepdecision/StepDecisionFlow.java](https://github.com/superdurable/dex/tree/main/examples/java/src/main/java/io/superdurable/dex/primitives/stepdecision/StepDecisionFlow.java)

<a id="close-decisions"></a>

## Close decisions

| Decision             | What it does                                                                                                 |
| -------------------- | ------------------------------------------------------------------------------------------------------------ |
| **GracefulComplete** | Stops this branch and marks the Flow to complete. The Flow completes when every branch and Step has stopped. |
| **DeadEnd**          | Stops this branch only.                                                                                      |
| **ForceComplete**    | Completes the Flow immediately.                                                                              |
| **ForceFail**        | Fails the Flow immediately.                                                                                  |

**GracefulComplete** and **ForceComplete** can carry an output. **ForceFail**
carries a failure reason. The Flow result lists each output with its Step type
and Step execution ID. When several Steps complete gracefully, the result
contains all their outputs.

**DeadEnd** stops this branch without marking the Flow to complete. A Flow with
no active Steps can keep running.

```java
case "graceful" -> {
    return StepDecision.gracefulComplete("done");
}
case "dead-end" -> {
    return StepDecision.goToMany(
            StepMovement.of(BranchWorker.class, "left"),
            StepMovement.of(BranchWorker.class, "right"));
}

return StepDecision.deadEnd();
```

Example: [examples/java/src/main/java/io/superdurable/dex/primitives/stepdecision/StepDecisionFlow.java](https://github.com/superdurable/dex/tree/main/examples/java/src/main/java/io/superdurable/dex/primitives/stepdecision/StepDecisionFlow.java)

```java
public StepDecision execute(final Context context, final Void input) {
    return StepDecision.forceFail("Workflow did not finish the task in time");
}

public StepDecision execute(final Context context, final Boolean workflowSuccessful) {
    return StepDecision.forceComplete("Workflow completed successfully");
}
```

Example: [examples/java/src/main/java/io/superdurable/dex/patterns/timeout/FlowGracefulTimeout.java](https://github.com/superdurable/dex/tree/main/examples/java/src/main/java/io/superdurable/dex/patterns/timeout/FlowGracefulTimeout.java)

<a id="cancellation-on-stepdecision"></a>

## Cancel other Steps

A **StepDecision** can cancel other active Steps.

- **CancelSteps** selects active Steps by Step type.
- **CancelSiblingSteps** selects active Steps that were triggered by the same
  parent Step execution.

An RPC can also cancel Steps by type. See
[Cancel running Steps](https://docs.superdurable.io/reference/server/runtime-data.md#cancel-running-steps). For how a
running attempt observes cancellation, see [Cancellation](https://docs.superdurable.io/reference/java/step-options.md#cancellation).

When Dex cancels a Step before its **Execute** commits, it returns the Channel
messages that the Step's wait consumed. They go back to the front of their
Channels, in their original order. A Step that the decision cancels also never
receives the messages that the same decision publishes. Neither applies when
the decision also closes the Flow with **ForceComplete** or **ForceFail**. See
[Canceled Steps return consumed messages](https://docs.superdurable.io/reference/server/runtime-data.md#canceled-step-messages).

```java
return StepDecision.goTo(RecordQuote.class, quote)
        .withCancelingSteps(carrierA, carrierB);
```

Example: [examples/java/src/main/java/io/superdurable/dex/primitives/stepdecision/StepDecisionFlow.java](https://github.com/superdurable/dex/tree/main/examples/java/src/main/java/io/superdurable/dex/primitives/stepdecision/StepDecisionFlow.java)

<a id="forcecompleteifchannelsempty"></a>

## ForceCompleteIfChannelsEmpty

**ForceCompleteIfChannelsEmpty** checks all named Channels in one atomic step.
If every one is empty, it completes the Flow. Otherwise, it goes to the given
next Steps. A Channel with queued messages is non-empty. A Channel also stays
non-empty after a Step consumes a message from it, until that Step's
**Execute** finishes. A message that a canceled Step returned is pending again,
so its Channel is non-empty too.

Use it to complete a Flow once its Channels are drained, so the Flow stays
short. See
[Drain External Channel](https://docs.superdurable.io/design-patterns/draining-channel-for-external-publishing.md)
for the full example.

```java
return StepDecision.forceCompleteIfChannelsEmpty(
        null,
        StepMovement.of(ProcessMessage.class, null),
        queueChannel);
```

Example: [examples/java/src/main/java/io/superdurable/dex/patterns/drainchannels/externalpublishing/DrainingExternalChannelFlow.java](https://github.com/superdurable/dex/tree/main/examples/java/src/main/java/io/superdurable/dex/patterns/drainchannels/externalpublishing/DrainingExternalChannelFlow.java)
