From 35f52f70ab27c19a062f6628970cff6657e330cf Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 24 Mar 2026 13:42:01 -0400 Subject: [PATCH 1/2] Fix TTS flush creating phantom contexts on providers like ElevenLabs When an interruption arrives before any LLM text reaches run_tts, the turn context ID exists but was never registered via create_audio_context. Calling flush_audio for this unregistered context sends a message to the provider (e.g. ElevenLabs) with a context_id it has never seen, which implicitly creates a server-side context that is never closed. After enough rapid interruptions these phantom contexts accumulate and exceed the providers limit (ElevenLabs: 5 simultaneous contexts, 1008 policy violation). Guard the flush call with audio_context_available so it only fires when the context was actually opened. Fixes #4114 --- src/pipecat/services/tts_service.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pipecat/services/tts_service.py b/src/pipecat/services/tts_service.py index 6d475bdc2..f6f4983ec 100644 --- a/src/pipecat/services/tts_service.py +++ b/src/pipecat/services/tts_service.py @@ -682,7 +682,12 @@ class TTSService(AIService): await self.remove_audio_context(self._turn_context_id) # Flush any pending audio so the TTS service closes the current context. - await self.flush_audio(context_id=self._turn_context_id) + # Only flush if the context was actually opened (text reached run_tts). + # When an interruption arrives before any text flows, the turn context ID + # exists but was never registered via create_audio_context, so flushing + # would send a message for a context the provider never opened. + if self._turn_context_id and self.audio_context_available(self._turn_context_id): + await self.flush_audio(context_id=self._turn_context_id) # Reset the turn context ID self._turn_context_id = None From e05bd5474323c3d54c9a95f2b6cc3fa87f927611 Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 24 Mar 2026 13:43:07 -0400 Subject: [PATCH 2/2] Add changelog for #4126 --- changelog/4126.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/4126.fixed.md diff --git a/changelog/4126.fixed.md b/changelog/4126.fixed.md new file mode 100644 index 000000000..205568bae --- /dev/null +++ b/changelog/4126.fixed.md @@ -0,0 +1 @@ +- Fixed ElevenLabs WebSocket disconnections (1008 "Maximum simultaneous contexts exceeded") caused by rapid user interruptions. When interruptions arrived before any TTS text was generated, phantom contexts were created on the ElevenLabs server that were never closed, eventually exceeding the 5-context limit.