# 2.6.0: Workflows can wait for an event

2026-08-25 · https://galley.themes.dev/changelog/v2-6-wait-for-event/

> ctx.waitForEvent pauses a workflow until something happens elsewhere, such as an approval or a payment, for up to 30 days, without holding a worker.

## waitForEvent

Some workflows need to stop until something outside them happens: a document signed, a payment settled, a reviewer pressing approve. Until now that meant polling in a loop of sleeps. Workflows can now wait for an event:

```ts
const kyc = await ctx.waitForEvent('kyc-approved', {
  event: 'kyc.approved',
  match: { userId: input.userId },
  timeout: '7d',
});
if (!kyc) return ctx.step('send-reminder', () => remind(input.userId));
```

Send the event from anywhere with `runnel.events.send('kyc.approved', { userId: 'usr_311' })`, or `POST /v1/events`. The workflow resumes with the event's payload, or with `null` when the timeout passes first.

While it waits, the run holds no worker and no concurrency slot. Waits can last up to 30 days. `match` compares top-level fields for equality; events that arrive before the workflow starts waiting are kept for 5 minutes, so a fast reply is not lost.

Available in Python as `await ctx.wait_for_event(…)` and in Go as `runnel.WaitForEvent(ctx, …)`.

## Fixes

- `ctx.sleep` longer than 7 days was rounded down to 7 days. The limit is now 365 days.
- A workflow step that returned `undefined` was stored as `null` and replayed as `null`.
- The dashboard's run timeline now shows sleeps and waits as gaps instead of a running step.
