#30052·open-webui

issue: Voice-call mode: TTS provider failure is silent and leaves the overlay stuck in "speaking"

Author: irespriteCreated Sep 15, 2026Updated Sep 17, 2026
Labelsbugconfirmed issue

Before Submitting

  • I searched open and closed issues and discussions for an existing report.
  • I checked whether this is already fixed on the dev branch or latest source (checked dev at a096961, 2026-09-14: CallOverlay.svelte differs from v0.11.3 by one i18n line; the code below is unchanged).
  • I understand that maintainers want a well-written issue before any code pull request.
  • I am using the latest available version of Open WebUI for my install method.
  • This is not a security vulnerability.

Installation Method

Docker

Open WebUI Version

v0.11.3 (ghcr.io/open-webui/open-webui:v0.11.3)

Operating System

Linux Docker host; client on macOS

Browser

Firefox (desktop, latest), private window, no service workers registered

Ollama Version

N/A (llama.cpp server via OpenAI-compatible connection)

Summary

In voice-call mode, when the configured OpenAI-compatible TTS provider is unreachable, the failure is completely silent: no toast, no console output in production builds, and the overlay stays in the "speaking" state until the user taps to interrupt. The text response is fine. The per-message Read Aloud button, by contrast, does show an error toast for the same failure.

TTS engine: OpenAI-compatible, pointed at a Kokoro-FastAPI container on the same Docker network. ENABLE_PERSISTENT_CONFIG=False; response auto-playback off.

Expected Behavior

One visible error saying speech failed; the overlay returns to listening; the text answer continues unaffected.

Actual Behavior

  • The text answer streams into the chat normally.
  • No toast is created. Verified with a MutationObserver on [data-sonner-toast] in the console, not just by eye. (Read Aloud on a message in the same session, same outage, created one toast per sentence: "Open WebUI: Server Connection Error".)
  • The overlay stays in "speaking" (with "Tap to interrupt") indefinitely; tapping to interrupt returns it to listening.
  • Network tab: one POST /api/v1/audio/speech per sentence, fired in parallel as the answer streams (16 for one answer), each 500 with {"detail":"Open WebUI: Server Connection Error"}.
  • Backend logs the cause correctly for each request (see logs).

Cause, from the v0.11.3 source (src/lib/components/chat/MessageInput/CallOverlay.svelte):

  1. fetchAudio (L505–552) handles the rejected synthesizeOpenAISpeech with .catch((error) => { console.error(error); return null; }). There is no toast.error on this path (the browser-kokoro branch just above it does toast). Nothing is added to audioCache.
  2. monitorAndPlayAudio (L560–608) dequeues the sentence, finds it isn't in audioCache, unshifts it back, waits 200 ms and repeats. Nothing ever settles it, so the loop runs until the next turn or an interrupt. That loop is the stuck "speaking" state.
  3. vite.config.ts L58 marks console.error as pure outside ENV=dev, so production builds have no console output either.

This is distinct from #28681 (fixed): there the TTS requests succeeded and play() was rejected; playAudio now settles in that case. Here no audio ever reaches playAudio, so that fix doesn't apply.

Steps to Reproduce

  1. Configure Audio → TTS engine "OpenAI" pointing at any OpenAI-compatible TTS server (Kokoro-FastAPI used here) and verify voice-call mode speaks replies.
  2. Stop the TTS server container (docker stop <tts-container>).
  3. Optional, to see toasts even if brief: in the browser console run new MutationObserver(() => { const t=[...document.querySelectorAll('[data-sonner-toast]')]; if (t.length) console.log('TOAST', t.map(x=>x.textContent)); }).observe(document.body,{childList:true,subtree:true});
  4. Open the call overlay and ask a question by voice.
  5. Observe: text answer appears; no toast; overlay stays in "speaking"; N × POST /api/v1/audio/speech → 500 in the Network tab.
  6. Control: with the server still stopped, press the Read Aloud button on a message. One toast per sentence appears.

Logs, Screenshots, and Config

Backend, one line per failed sentence (16 in one answer):

ERROR | open_webui.routers.audio:_tts_openai:401 - Cannot connect to host kokoro:8880 ssl:default [Connect call failed ('172.18.0.8', 8880)]

or, when the provider's IP is not in the aiohttp DNS cache:

ERROR | open_webui.routers.audio:_tts_openai:401 - Cannot connect to host kokoro:8880 ssl:default [Name or service not known]

Browser: no console errors (expected, given the production pure setting); Network shows the 500s. No service worker registered, caches.keys() empty.

Timing note, in case it matters for the fix: when the provider was used within the last 300 s, its address is still in the shared aiohttp session's DNS cache (AIOHTTP_POOL_DNS_TTL default), so each failed request waits ~11 s for the TCP connect to the dead address (Connect call failed). With a cold cache it fails in ~45 ms (Name or service not known). A user who has just been using voice therefore sees ~11 s of "speaking" per sentence, then nothing.

Config: default audio settings apart from the OpenAI-compatible TTS URL/key and voice; ENABLE_PERSISTENT_CONFIG=False; behind a reverse proxy (not involved: the 500s are Open WebUI's own responses).

Additional Information

Suggested behaviour, one turn at a time: on the first TTS failure in an assistant turn, show one toast.error, mark TTS as failed for that turn, abort the audio monitor (so the overlay returns to listening), and don't request TTS for the turn's remaining sentences; reset on the next turn. The text response should be unaffected. Happy to test a fix on dev.

Related:

  • #28681 — call mode silent when play() is rejected (fixed in v0.11.3; different trigger, see above).
  • #26974 — call mode mic stops capturing (open; different problem, same overlay).
  • #12652 — older backend hang on an unavailable TTS provider (v0.6.2); the backend side now returns a clean 500 promptly.
  • #17316 — Read Aloud showed the provider error "many times" (one toast per sentence). Read Aloud's remaining issue (it keeps requesting sentences after the first failure) is minor and separate from this report.