issue: Azure TTS fails on ampersand in SSML: 400 “Invalid char ‘&’ …” #6561

Closed
opened 2025-11-11 16:59:34 -06:00 by GiteaMirror · 1 comment
Owner

Originally created by @rbb-dev on GitHub (Oct 1, 2025).

Check Existing Issues

  • I have searched for any existing and/or related issues.
  • I have searched for any existing and/or related discussions.
  • I am using the latest version of Open WebUI.

Installation Method

Git Clone

Open WebUI Version

v0.6.32

Ollama Version (if applicable)

No response

Operating System

Ubuntu 24.04

Browser (if applicable)

No response

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both Open WebUI and Ollama.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have provided every relevant configuration, setting, and environment variable used in my setup.
  • I have clearly listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc).
  • I have documented step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation. My steps:
  • Start with the initial platform/version/OS and dependencies used,
  • Specify exact install/launch/configure commands,
  • List URLs visited, user input (incl. example values/emails/passwords if needed),
  • Describe all options and toggles enabled or changed,
  • Include any files or environmental changes,
  • Identify the expected and actual result at each stage,
  • Ensure any reasonably skilled user can follow and hit the same issue.

Expected Behavior

Clicking the speaker icon should generate audio for any plain text, including text containing special characters like ‘&’.
Open WebUI should escape SSML‑sensitive characters before sending the payload to Azure Cognitive Services, so the request succeeds and audio plays.

Actual Behavior

Azure TTS returns HTTP 400 with “Invalid char ‘&’ … found in SSML. Please escape it before use.” when the input contains an ampersand.
No audio is produced for that section of text. Server logs show a stack trace from open_webui/routers/audio.py around the TTS request.

Steps to Reproduce

Configure Text‑to‑Speech provider as Azure Cognitive Services.
In any chat, click the speaker icon to play TTS for a message that contains an ampersand, for example:
“Fish & chips for dinner.”
“R&D update for A&B.”
Watch the server logs while TTS starts. You will see HTTP 400 errors from the Azure endpoint and a stack trace.
Audio does not play.
if the text section is large and punctuation splitting is used, part of audio is missing

Logs & Screenshots

2025-10-01 20:57:47.279 | ERROR    | open_webui.routers.audio:speech:489 - 400, message="Invalid char '&' at position 46 found in SSML. Please escape it before use.", url='https://australiaeast.tts.speech.microsoft.com/cognitiveservices/v1'
Traceback (most recent call last):

  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.11/multiprocessing/spawn.py", line 122, in spawn_main
    exitcode = _main(fd, parent_sentinel)
               │     │   └ 6
               │     └ 9
               └ <function _main at 0xed94f0306340>
  File "/usr/local/lib/python3.11/multiprocessing/spawn.py", line 135, in _main
    return self._bootstrap(parent_sentinel)
           │    │          └ 6
           │    └ <function BaseProcess._bootstrap at 0xed94f0570ae0>
           └ <SpawnProcess name='SpawnProcess-1' parent=1 started>
  File "/usr/local/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
    │    └ <function BaseProcess.run at 0xed94f0570040>
    └ <SpawnProcess name='SpawnProcess-1' parent=1 started>
  File "/usr/local/lib/python3.11/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
    │    │        │    │        │    └ {'config': <uvicorn.config.Config object at 0xed94f0302190>, 'target': <bound method Process.target of <uvicorn.supervisors.m...
    │    │        │    │        └ <SpawnProcess name='SpawnProcess-1' parent=1 started>
    │    │        │    └ ()
    │    │        └ <SpawnProcess name='SpawnProcess-1' parent=1 started>
    │    └ <function subprocess_started at 0xed94ef545440>
    └ <SpawnProcess name='SpawnProcess-1' parent=1 started>
  File "/usr/local/lib/python3.11/site-packages/uvicorn/_subprocess.py", line 80, in subprocess_started

Additional Information

No response

Originally created by @rbb-dev on GitHub (Oct 1, 2025). ### Check Existing Issues - [x] I have searched for any existing and/or related issues. - [x] I have searched for any existing and/or related discussions. - [x] I am using the latest version of Open WebUI. ### Installation Method Git Clone ### Open WebUI Version v0.6.32 ### Ollama Version (if applicable) _No response_ ### Operating System Ubuntu 24.04 ### Browser (if applicable) _No response_ ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** Open WebUI and Ollama. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have **provided every relevant configuration, setting, and environment variable used in my setup.** - [x] I have clearly **listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup** (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc). - [x] I have documented **step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation**. My steps: - Start with the initial platform/version/OS and dependencies used, - Specify exact install/launch/configure commands, - List URLs visited, user input (incl. example values/emails/passwords if needed), - Describe all options and toggles enabled or changed, - Include any files or environmental changes, - Identify the expected and actual result at each stage, - Ensure any reasonably skilled user can follow and hit the same issue. ### Expected Behavior Clicking the speaker icon should generate audio for any plain text, including text containing special characters like ‘&’. Open WebUI should escape SSML‑sensitive characters before sending the payload to Azure Cognitive Services, so the request succeeds and audio plays. ### Actual Behavior Azure TTS returns HTTP 400 with “Invalid char ‘&’ … found in SSML. Please escape it before use.” when the input contains an ampersand. No audio is produced for that section of text. Server logs show a stack trace from open_webui/routers/audio.py around the TTS request. ### Steps to Reproduce Configure Text‑to‑Speech provider as Azure Cognitive Services. In any chat, click the speaker icon to play TTS for a message that contains an ampersand, for example: “Fish & chips for dinner.” “R&D update for A&B.” Watch the server logs while TTS starts. You will see HTTP 400 errors from the Azure endpoint and a stack trace. Audio does not play. if the text section is large and punctuation splitting is used, part of audio is missing ### Logs & Screenshots ```text 2025-10-01 20:57:47.279 | ERROR | open_webui.routers.audio:speech:489 - 400, message="Invalid char '&' at position 46 found in SSML. Please escape it before use.", url='https://australiaeast.tts.speech.microsoft.com/cognitiveservices/v1' Traceback (most recent call last): File "<string>", line 1, in <module> File "/usr/local/lib/python3.11/multiprocessing/spawn.py", line 122, in spawn_main exitcode = _main(fd, parent_sentinel) │ │ └ 6 │ └ 9 └ <function _main at 0xed94f0306340> File "/usr/local/lib/python3.11/multiprocessing/spawn.py", line 135, in _main return self._bootstrap(parent_sentinel) │ │ └ 6 │ └ <function BaseProcess._bootstrap at 0xed94f0570ae0> └ <SpawnProcess name='SpawnProcess-1' parent=1 started> File "/usr/local/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap self.run() │ └ <function BaseProcess.run at 0xed94f0570040> └ <SpawnProcess name='SpawnProcess-1' parent=1 started> File "/usr/local/lib/python3.11/multiprocessing/process.py", line 108, in run self._target(*self._args, **self._kwargs) │ │ │ │ │ └ {'config': <uvicorn.config.Config object at 0xed94f0302190>, 'target': <bound method Process.target of <uvicorn.supervisors.m... │ │ │ │ └ <SpawnProcess name='SpawnProcess-1' parent=1 started> │ │ │ └ () │ │ └ <SpawnProcess name='SpawnProcess-1' parent=1 started> │ └ <function subprocess_started at 0xed94ef545440> └ <SpawnProcess name='SpawnProcess-1' parent=1 started> File "/usr/local/lib/python3.11/site-packages/uvicorn/_subprocess.py", line 80, in subprocess_started ``` ### Additional Information _No response_
GiteaMirror added the bug label 2025-11-11 16:59:34 -06:00
Author
Owner

@tjbck commented on GitHub (Oct 2, 2025):

2e75c6dbdf in dev!

@tjbck commented on GitHub (Oct 2, 2025): 2e75c6dbdf0658e6689fba1e477f8021a3e85d54 in dev!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#6561