#730·sonner

Bug: Updating toast during dismiss animation results in skipped display

Author: lucaslee-cryptoCreated Dec 31, 2025Updated Aug 9, 2026

Context

I am using a toast to display the status of a certain process.

I want to first show a toast that display a pending message which last for at most 1 second. If the process is completed within 1 second, the existing pending message should be replaced with a success/error message. Otherwise, the toast that contains the pending message should be auto-dismissed, and a new toast that display a success/error message should be displayed after the process is completed.

The time it takes for the process to complete varies and is not predictable.

I implemented this by using a fixed toastId and let the toaster handles accordingly. The behavior is correct most of the time.

Case 1: The process finishes within 1 second (950ms in this demo), replacing existing message.

https://github.com/user-attachments/assets/c2a306f8-79bd-49b2-ab4c-e70ccfed5fd1

Case 2: The process finishes after 1 second (1250ms in this demo), auto-dismissing the first message, then display a new toast.

https://github.com/user-attachments/assets/fd3cc6e5-8caf-44ab-8e94-9ba6583922e7

However, if the process finishes just slightly after 1 second (~1050 - 1200ms), the following bug arises.

Bug Description

When trying to update the toast during the dismiss animation (hardcoded at 200ms), the content of the dismissing toast will be replaced during the animation without cancelling the dismiss animation or display a new toast, resulting in the display of the second message being skipped.

https://github.com/user-attachments/assets/35e51ff7-5438-4390-8875-33ce3b057044

Code Demo

javascript
<Button
  onClick={() => {
    toast.warning('This is the first toast', {
      id: 'auto-toast',
      duration: 1000,
    })

    setTimeout(() => {
      toast.success('This is the second toast', {
        id: 'auto-toast',
        duration: 1000,
      })
    }, 1050) // Change this timeout duration accordingly
  }}
>
  Auto Content Update
</Button>

Expected Behaviour

The display should either follows Case 1, if we allows a 'grace' period where existing toast could be reused during the dismiss animation, or Case 2 if we strictly follows the toast duration option.