T022

How do I properly configure wrap-up activity transitions so workers don't get stuck after reservation timeout?

Ticket

Hey Twilio support team, I'm hoping someone can help me understand if I'm setting something up wrong, or point me to documentation I might be missing, because I've been going in circles on this for a few days now and I'm not sure if it's a configuration gap on my end or something else. Some context: I'm a solo dev maintaining a Flex 2.7.1 deployment, running the standard Flex UI on Chrome 124. We have a fairly simple voice workflow — nothing too exotic. Workers sit in Available, get a reservation, and if they don't accept within our configured timeout window, the reservation times out and the task gets re-evaluated (I can see `task_re_evaluated_reason: reservation_timeout` in the TaskRouter logs, so that part is working as expected). The thing I'm trying to understand is: after a reservation timeout fires, is there a correct way to make sure the worker automatically transitions to a specific Activity? Because what I'm observing is that the worker stays in Available (Activity SID `WA3f8b2c19d4e05a1b67890abcdef1234`) after the timeout, which is actually what we want in most cases — but then sometimes, seemingly at random, the worker gets pushed into an Unavailable state instead (Activity SID `WAc7d92e0f1a2b3456789012345678abcd`), and they have to manually click back to Available to receive tasks again. I initially thought this might be related to our `DequeuePostWorkActivitySid` setting, but the timeouts I'm describing happen before the task is ever accepted, so post-work wrap-up shouldn't even be in play here, right? Like the worker never entered wrap-up, the reservation just timed out. Here's what I've been doing to try to reproduce it consistently: 1. Worker logs in, goes Available — Workspace is `WS4a1b2c3d4e5f6789012345678901abcd` 2. A voice task comes in, reservation `WR9z8y7x6w5v4u3t2s1r0q9p8o7n6m5l` is created 3. Worker does NOT accept — just lets it sit past the timeout threshold 4. TaskRouter logs show the reservation timeout and task re-evaluation, as expected 5. Worker's activity in the TaskRouter Worker page flips to Unavailable — worker SID is `WK2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7` Step 5 is what I don't understand. I haven't set any listener or action that should be pushing the worker to Unavailable on a reservation timeout. I've checked our plugins and we don't have any `reservation.timeout` handler calling `worker.update({ActivitySid: …})` for the Unavailable SID. Our plugin code only touches the `beforeAcceptTask` override for some logging. Is there a built-in Flex or TaskRouter behavior where a reservation timeout automatically moves the worker to a fallback activity? And if so, is there somewhere I configure which activity that should be? I've read through the TaskRouter Worker Activity docs and the Flex wrap-up docs but I can't find anything that explicitly describes this behavior happening on timeout rather than on task completion. I'd also just like to confirm: is this expected to be deterministic? Because the part that really puzzles me is that it doesn't happen every time. Maybe 30-40% of timeout events result in the worker going Unavailable. The other 60-70% the worker stays Available just fine. If this were a config option I'd set, I'd expect it to happen 100% of the time. I've looked at the Status Report download from the Flex UI and I don't see any 45600 or 45601 errors logged around the time these transitions happen, so it doesn't seem like a plugin crash is causing a side effect. Checked `Flex.Monitor.getErrors()` output too and nothing stands out. Any guidance on what's happening here and what knob I should be turning would be really appreciated. Happy to provide more logs or SIDs if needed. Thanks so much

Gold label: config / medium

this appears to point to the agent offline activity setting which can set an agent to offline/unavailable if a reservation is missed.

Results by run

openai · gpt-5.5

2026-10-04 17:23 UTC · prompt ef0017a

bug (wrong)
medium (correct)
escalate: yes

Summary

Workers intermittently transition to Unavailable after an unaccepted reservation times out, even though reservation timeout should re-evaluate the task and DequeuePostWorkActivitySid should only apply after an accepted dequeue/post-work flow.

Suggested first response

Thanks for the detailed reproduction steps and SIDs. You’re correct that DequeuePostWorkActivitySid applies to post-dequeue/post-call behavior, not to a reservation that was never accepted; a reservation timeout should leave the task eligible for re-evaluation rather than deterministically moving the worker to a fallback wrap-up activity. Since the worker is intermittently being moved to Unavailable without an apparent plugin handler or client-side error, we’d like to investigate this as unexpected behavior. Please send a few exact timestamps with the affected Worker SID, Reservation SID, Task SID, and Workspace SID for both a timeout that stayed Available and one that moved to Unavailable, and we’ll review the worker activity transition history and TaskRouter/Flex events.

KB citations

kb-008

487 output tokens · 6.4s · 1 attempt(s)

anthropic · claude-sonnet-4-6

2026-10-04 17:20 UTC · prompt ef0017a

how_to (wrong)
low (wrong)
escalate: no

Summary

Developer is trying to understand why workers intermittently transition to Unavailable after a reservation timeout in Flex/TaskRouter, and wants to know how to configure or control that behavior.

Suggested first response

Thank you for the detailed write-up — this is a great question and the intermittent nature is the key clue here. To address your core question: TaskRouter does have a built-in mechanism called the 'Activity on Timeout' (or 'timeout activity') setting at the Workflow level, specifically on the Workflow's Routing Step or Filter configuration. If a reservation times out, TaskRouter can automatically move the worker to a designated Activity SID — but if this is not explicitly set, the behavior can fall back to workspace-level defaults or remain unchanged, which may explain why you see it happen inconsistently rather than 100% of the time. The non-determinism you're observing (30–40% of timeouts) is a strong signal that this is not a deliberately configured transition, but rather a race condition or a workspace/workflow default being applied inconsistently — possibly influenced by client connectivity state at the moment of timeout (e.g., the Flex client briefly losing its WebSocket connection to TaskRouter at the same moment the timeout fires, which can cause TaskRouter to treat the worker as unreachable and move them to an offline-adjacent activity). Here are the steps we'd recommend: (1) Check your Workflow configuration in the Twilio Console under TaskRouter > Workspaces > your workspace > Workflows, and inspect each Routing Step for any 'Activity on Timeout' or 'Activity on Reservation Timeout' field — note the SID configured there, if any. (2) Review your Workspace's default Activity setting, as this can serve as a fallback. (3) Pull the Worker Activity history log (available via the TaskRouter REST API at /v1/Workspaces/{WorkspaceSid}/Workers/{WorkerSid}/WorkerChannels or the Worker Statistics endpoint) for the affected worker around the time of a timeout event to see what triggered the activity change — the 'reason' field in the activity transition event should indicate whether it was a TaskRouter-initiated change or a client-initiated one. (4) Check for any Flex Insights or Event Streams data around those timestamps for the worker SID you provided. You are correct that DequeuePostWorkActivitySid would not apply here since the task was never accepted. Could you confirm whether you have any 'Activity on Timeout' SID configured in your Workflow Routing Steps, and share the output of a GET request to your Workflow resource so we can review the full configuration? That will help us determine whether this is a configuration gap or something worth escalating further.

KB citations

kb-008

634 output tokens · 18.3s · 1 attempt(s)