From a18aa738e0f792c56e22574a15e30c9a6d8917a1 Mon Sep 17 00:00:00 2001 From: Om Chauhan Date: Sat, 21 Feb 2026 18:26:31 +0530 Subject: [PATCH 1/3] fix(realtime): handle response_cancel_not_active as non-fatal --- src/pipecat/services/grok/realtime/llm.py | 7 +++++-- src/pipecat/services/openai/realtime/llm.py | 9 ++++++--- src/pipecat/services/openai_realtime_beta/openai.py | 9 ++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/pipecat/services/grok/realtime/llm.py b/src/pipecat/services/grok/realtime/llm.py index e1355ce31..0d3687a26 100644 --- a/src/pipecat/services/grok/realtime/llm.py +++ b/src/pipecat/services/grok/realtime/llm.py @@ -511,8 +511,11 @@ class GrokRealtimeLLMService(LLMService): elif evt.type == "response.function_call_arguments.done": await self._handle_evt_function_call_arguments_done(evt) elif evt.type == "error": - await self._handle_evt_error(evt) - return + if evt.error.code == "response_cancel_not_active": + logger.warning(f"Non-fatal API error: {evt.error.message}") + else: + await self._handle_evt_error(evt) + return async def _handle_evt_conversation_created(self, evt): """Handle conversation.created event - first event after connecting.""" diff --git a/src/pipecat/services/openai/realtime/llm.py b/src/pipecat/services/openai/realtime/llm.py index cf249408c..ebd1fbdbc 100644 --- a/src/pipecat/services/openai/realtime/llm.py +++ b/src/pipecat/services/openai/realtime/llm.py @@ -577,9 +577,12 @@ class OpenAIRealtimeLLMService(LLMService): await self._handle_evt_function_call_arguments_done(evt) elif evt.type == "error": if not await self._maybe_handle_evt_retrieve_conversation_item_error(evt): - await self._handle_evt_error(evt) - # errors are fatal, so exit the receive loop - return + if evt.error.code == "response_cancel_not_active": + logger.warning(f"Non-fatal API error: {evt.error.message}") + else: + await self._handle_evt_error(evt) + # errors are fatal, so exit the receive loop + return @traced_openai_realtime(operation="llm_setup") async def _handle_evt_session_created(self, evt): diff --git a/src/pipecat/services/openai_realtime_beta/openai.py b/src/pipecat/services/openai_realtime_beta/openai.py index 1199d8556..808fbb053 100644 --- a/src/pipecat/services/openai_realtime_beta/openai.py +++ b/src/pipecat/services/openai_realtime_beta/openai.py @@ -503,9 +503,12 @@ class OpenAIRealtimeBetaLLMService(LLMService): await self._handle_evt_audio_transcript_delta(evt) elif evt.type == "error": if not await self._maybe_handle_evt_retrieve_conversation_item_error(evt): - await self._handle_evt_error(evt) - # errors are fatal, so exit the receive loop - return + if evt.error.code == "response_cancel_not_active": + logger.warning(f"Non-fatal API error: {evt.error.message}") + else: + await self._handle_evt_error(evt) + # errors are fatal, so exit the receive loop + return @traced_openai_realtime(operation="llm_setup") async def _handle_evt_session_created(self, evt): From b390dc369c67b93fb04e7797069ed2a7402334bc Mon Sep 17 00:00:00 2001 From: Om Chauhan Date: Sat, 21 Feb 2026 18:33:29 +0530 Subject: [PATCH 2/3] added changelog --- changelog/3795.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/3795.fixed.md diff --git a/changelog/3795.fixed.md b/changelog/3795.fixed.md new file mode 100644 index 000000000..8c231abac --- /dev/null +++ b/changelog/3795.fixed.md @@ -0,0 +1 @@ +- Treated `response_cancel_not_active` as a non-fatal error in realtime services (`OpenAIRealtimeLLMService`, `GrokRealtimeLLMService`, `OpenAIRealtimeBetaLLMService`) to prevent WebSocket disconnection when cancelling an inactive response. \ No newline at end of file From ece434383991f477d725353c2e503842d6542963 Mon Sep 17 00:00:00 2001 From: Om Chauhan Date: Sun, 1 Mar 2026 12:25:42 +0530 Subject: [PATCH 3/3] changed log level to debug --- src/pipecat/services/grok/realtime/llm.py | 2 +- src/pipecat/services/openai/realtime/llm.py | 2 +- src/pipecat/services/openai_realtime_beta/openai.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pipecat/services/grok/realtime/llm.py b/src/pipecat/services/grok/realtime/llm.py index 0d3687a26..f717e408b 100644 --- a/src/pipecat/services/grok/realtime/llm.py +++ b/src/pipecat/services/grok/realtime/llm.py @@ -512,7 +512,7 @@ class GrokRealtimeLLMService(LLMService): await self._handle_evt_function_call_arguments_done(evt) elif evt.type == "error": if evt.error.code == "response_cancel_not_active": - logger.warning(f"Non-fatal API error: {evt.error.message}") + logger.debug(f"{self} {evt.error.message}") else: await self._handle_evt_error(evt) return diff --git a/src/pipecat/services/openai/realtime/llm.py b/src/pipecat/services/openai/realtime/llm.py index ebd1fbdbc..57efafbef 100644 --- a/src/pipecat/services/openai/realtime/llm.py +++ b/src/pipecat/services/openai/realtime/llm.py @@ -578,7 +578,7 @@ class OpenAIRealtimeLLMService(LLMService): elif evt.type == "error": if not await self._maybe_handle_evt_retrieve_conversation_item_error(evt): if evt.error.code == "response_cancel_not_active": - logger.warning(f"Non-fatal API error: {evt.error.message}") + logger.debug(f"{self} {evt.error.message}") else: await self._handle_evt_error(evt) # errors are fatal, so exit the receive loop diff --git a/src/pipecat/services/openai_realtime_beta/openai.py b/src/pipecat/services/openai_realtime_beta/openai.py index 808fbb053..ffa1f4207 100644 --- a/src/pipecat/services/openai_realtime_beta/openai.py +++ b/src/pipecat/services/openai_realtime_beta/openai.py @@ -504,7 +504,7 @@ class OpenAIRealtimeBetaLLMService(LLMService): elif evt.type == "error": if not await self._maybe_handle_evt_retrieve_conversation_item_error(evt): if evt.error.code == "response_cancel_not_active": - logger.warning(f"Non-fatal API error: {evt.error.message}") + logger.debug(f"{self} {evt.error.message}") else: await self._handle_evt_error(evt) # errors are fatal, so exit the receive loop