Issue
This article explains why a Twilio TaskRouter Reservation may trigger a reservation.canceled event instead of the expected reservation.timeout event. It outlines the technical discrepancies between system-enforced timeouts and cancellation triggers, helping developers identify the root causes behind unexpected reservation states and ensure accurate event tracking within their workflow logic.
Product
Twilio Flex
Environment
legacy Twilio Console
Cause
This occurs because the agent (Worker) attempted to accept the Task, which put the Reservation into an internal onHold state while the communication channel was being set up. While a Reservation is onHold, TaskRouter pauses the normal Reservation timeout.
This is because reservation.timeout events are meant for no-response scenarios. In this scenario, the Worker has responded with intent to accept the Task.
If setup completes, the Reservation transitions to accepted (reservation.accepted).
If setup fails, the Reservation transitions to canceled (reservation.canceled).
What this looks like step by step
- Agent clicks Accept (or your system calls Accept via API)
- TaskRouter puts the Reservation in onHold and starts setup
- Voice: create a Conference and add the agent and caller
- Messaging: create the Interaction and setup participants in the Conversation
- While onHold
- Reservation timeouts are ignored
- onHold can last up to several minutes
- Outcomes
- Setup succeeds → Reservation transitions to
accepted - Setup fails (errors creating the Conference, joining the Conversation, etc.) → Reservation transitions to
canceled
- Setup succeeds → Reservation transitions to
Procedure
- Collect client-side diagnostics: capture browser Twilio Console logs and a HAR/network trace from the moment the agent clicks Accept through the failure. Note the exact UTC timestamp and the affected Worker SID.
- Escalate to Twilio Support within 7 days with concrete examples. Include Task SID or Reservation SID, plus client-side logs if possible.
Additional Information
- onHold is an internal Reservation state used to prevent premature timeouts during setup. It is not exposed as a public Reservation status in the API.
- This behavior applies to both Flex-managed and custom TaskRouter implementations.