
TTS /api/v1/audio/speech does not inject `voice` from server config, breaking third-party clients
快速结论:当 Open WebUI 配置了 OpenAI TTS 引擎并使用第三方客户端(如 iOS 上的 Open Relay)调用 TTS 时,如果客户端请求中没有包含 voice 字段,Open WebUI 不会自动从服务器配置中注入 voice 值,导致 OpenAI 返回 400 Bad Request。优先检查 TTS_VOICE 配置项是否正确设置,以及确认第三方客户端是否主动发送 voice 字段。
问题场景
使用 Open WebUI 配置了 OpenAI TTS 引擎(如 tts-1 模型、alloy 语音),并通过第三方客户端(例如 iOS 上的 Open Relay)调用 /api/v1/audio/speech 端点触发 TTS 时,服务器返回 400 错误。内置浏览器 UI 可以正常使用,因为它会在请求体中发送 voice 字段,但其他 API 客户端同样一个字段时会触发此问题。
报错原文
aiohttp.client_exceptions.ClientResponseError: 400, message='Bad Request', url='https://api.openai.com/v1/audio/speech'
原因分析
Open WebUI 的 /api/v1/audio/speech 端点会从服务器配置中注入 model 字段(如果客户端未提供),但不会同样注入 TTS_VOICE 配置值。OpenAI 的 TTS API 要求 voice 为必填字段,当第三方客户端未主动发送此字段时,OpenAI 返回 400 错误。可能原因:open_webui/routers/audio.py 中没有实现对 voice 字段的 fallback 逻辑。
环境排查
- Open WebUI 版本(确认是否包含修复此问题的 dev 分支或正式版本)
- OpenAI TTS 引擎配置:确认操作界面中已正确设置
TTS_MODEL和TTS_VOICE(例如tts-1和alloy) - 第三方客户端:确认客户端是否主动发送
voice字段(内置 UI 会发送,但某些第三方客户端可能不会) - TTS API 基础 URL:确认是否指向 Open WebUI 实例,而不是直接指向 OpenAI
解决步骤
- 首先确认 Open WebUI 配置中
TTS_VOICE已设置(例如alloy或其他有效值)。 - 检查以验证第三方客户端是否确实没有发送
voice字段。可以使用抓包工具,或者在 Open WebUI 服务日志中查找请求体内容。 - 如果确认是 Open WebUI 本身未注入
voice,则需要修改 Open WebUI 代码。根据 Issue 中的建议修复,修改文件open_webui/routers/audio.py,在现有model注入代码附近(约第 417 行)添加:payload['model'] = request.app.state.config.TTS_MODEL # 添加如下行: if 'voice' not in payload or not payload['voice']: payload['voice'] = request.app.state.config.TTS_VOICE注意:该修复已标记为在 dev 分支中处理。如果是自部署实例,未修复前可优先尝试手动应用此补丁。此修改不会覆盖客户端已发送的
voice,仅当字段缺失或为空时回退到服务器配置。 - 如果无法修改代码,可尝试在第三方客户端中强制添加
voice字段(例如设置为 “alloy” 等有效值)。
验证方法
应用修复后,使用第三方客户端(如 curl 命令或 Open Relay)发送 TTS 请求,不需要包含 voice 字段。确认返回 200 成功音频,且日志中没有 400 错误。也可以直接通过 curl 验证:
curl -X POST "http://your-open-webui-instance/api/v1/audio/speech" \
-H "Authorization: Bearer your-token" \
-H "Content-Type: application/json" \
-d '{"input": "Hello world", "model": "tts-1"}'
如果返回的是音频流(而非 400 错误),则问题已解决。

![[Bug]: FlashInfer fused allreduce + residual RMSNorm + quant produces corrupted output with FP32 norm weights](https://www.chat-gpts.plus/wp-content/uploads/2026/07/48324-bc8edd74-768x403.jpg)

