Forks and Branches

Use a fork for concurrent branches that each contain multiple sequential operations.

Select joined branches

WOML
<fork id="distribution" join="instagram facebook">
  <branch id="tiktok"><step id="publishTikTok"><script>return publishTikTok();</script></step></branch>
  <branch id="instagram"><step id="publishInstagram"><script>return publishInstagram();</script></step></branch>
  <branch id="facebook"><step id="publishFacebook"><script>return publishFacebook();</script></step></branch>
</fork>

join accepts all, none, or whitespace-separated branch IDs. It defaults to all. The main continuation waits only for selected branches, and only joined outputs become visible afterward.

Execution behavior

Branches start concurrently and remain sequential internally. Sibling outputs are never visible. Unjoined work can continue after the main route is released, but the workflow does not report success until every branch settles. Any branch failure still makes the overall workflow fail.

Use <choose> or <switch> inside a branch when that route needs decisions.

Build a distribution workflow

WOML
<fork id="distribution" join="instagram facebook">
  <branch id="tiktok" name="TikTok">
    <step id="prepareTikTok"><script>return { format: "vertical" };</script></step>
    <step id="publishTikTok"><script>return publishTikTok(context.steps.prepareTikTok);</script></step>
  </branch>

  <branch id="instagram" name="Instagram">
    <step id="prepareInstagram"><script>return { format: "square" };</script></step>
    <step id="publishInstagram"><script>return publishInstagram(context.steps.prepareInstagram);</script></step>
  </branch>

  <branch id="facebook" name="Facebook">
    <step id="publishFacebook"><script>return publishFacebook();</script></step>
  </branch>
</fork>

<step id="recordPrimaryDistribution">
  <script>
    return {
      instagram: context.steps.publishInstagram,
      facebook: context.steps.publishFacebook
    };
  </script>
</step>

All three branches start independently. The main continuation waits for Instagram and Facebook because they are named in join. It does not wait for TikTok before recordPrimaryDistribution becomes eligible, and TikTok outputs are deliberately unavailable there.

Understand joins

Use join="all" when every branch must finish before main work continues. Use a whitespace-separated branch list when only selected branches produce required main-route data. Use join="none" for fire-and-continue behavior within the same run.

An unjoined branch is not abandoned. WOML still owns it, records its outcome, and waits for every branch before reporting final workflow success. An unjoined failure can therefore make the overall run fail even though the main continuation already executed.

Keep branch data isolated

Each branch sees context from before the fork and earlier outputs in that same branch. It never reads sibling outputs. Completion timing cannot make a sibling value appear.

Use a downstream main step to combine joined outputs. If one lane requires another lane's output, they are not independent and should probably be sequential instead of sibling branches.

Nested forks inside a fork-owned subtree are rejected in v1. Choices, switches, parallel groups, approvals, and multiple steps may be used inside a branch.