From 921a7a46cb286cbf073f18ef7eb0c44cb0926a8e Mon Sep 17 00:00:00 2001 From: filipi87 Date: Wed, 6 May 2026 15:35:43 -0300 Subject: [PATCH 1/2] Fix interruption blocked by slow non-uninterruptible frame in queue When a non-uninterruptible frame was being processed slowly and an uninterruptible frame was waiting in the queue, _start_interruption skipped task cancellation. This caused interruptions to stall until the slow frame finished, even though it had no reason to block them. The fix: only skip cancellation when the *current* frame is uninterruptible. Uninterruptible frames already in the queue are preserved regardless, because __create_process_task calls __reset_process_queue internally, which always retains them. Fixes: https://github.com/pipecat-ai/pipecat/issues/4412 --- src/pipecat/processors/frame_processor.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pipecat/processors/frame_processor.py b/src/pipecat/processors/frame_processor.py index 0ee22a642..05abfceb4 100644 --- a/src/pipecat/processors/frame_processor.py +++ b/src/pipecat/processors/frame_processor.py @@ -877,14 +877,19 @@ class FrameProcessor(BaseObject): current_is_uninterruptible = isinstance( self.__process_current_frame, UninterruptibleFrame ) - if current_is_uninterruptible or self.__process_queue.has_uninterruptible: - # We don't want to cancel an UninterruptibleFrame (either the - # one currently being processed or one waiting in the queue), - # so we simply cleanup the queue keeping only - # UninterruptibleFrames. + if current_is_uninterruptible: + # The frame currently being processed is uninterruptible, so we + # must not cancel it. Just flush non-uninterruptible frames from + # the queue; any uninterruptible ones will be kept and processed + # after the current frame finishes. self.__reset_process_queue() else: - # Cancel and re-create the process task. + # Cancel and re-create the process task. Previously this branch + # was skipped when the queue contained an uninterruptible frame, + # which caused slow non-uninterruptible frames to block + # interruptions. Uninterruptible queued frames are safe here + # because __create_process_task calls __reset_process_queue + # internally, which always preserves them. await self.__cancel_process_task() self.__create_process_task() except Exception as e: From 36f6e22aee38e8ca409f28a77d0587d4561f4114 Mon Sep 17 00:00:00 2001 From: filipi87 Date: Wed, 6 May 2026 15:39:27 -0300 Subject: [PATCH 2/2] Adding changelog for the interruption fix. --- changelog/4434.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/4434.fixed.md diff --git a/changelog/4434.fixed.md b/changelog/4434.fixed.md new file mode 100644 index 000000000..28ba766ca --- /dev/null +++ b/changelog/4434.fixed.md @@ -0,0 +1 @@ +- Fixed interruptions being delayed when a slow non-uninterruptible frame was processing and an uninterruptible frame was waiting in the queue. The bot would stall until the slow frame finished instead of cancelling it immediately on interruption.