#1446·OpenMAIC

[Bug]: Azure TTS rejects all non-Chinese voices — xml:lang is hard-coded to zh-CN

Author: southerlyswellCreated Sep 10, 2026Updated Sep 16, 2026

Bug Description

generateAzureTTS() in lib/audio/tts-providers.ts builds SSML with xml:lang='zh-CN' on both <speak> and <voice>, regardless of which voice the user selected:

typescript
// lib/audio/tts-providers.ts:657 (main @ 64621adf)
<speak version='1.0' xml:lang='zh-CN'>
  <voice xml:lang='zh-CN' name='${config.voice}'>

Azure validates that the SSML locale agrees with the selected voice and rejects the request, so only zh-CN voices can ever be synthesised. The Azure provider is therefore effectively unusable outside Chinese, even though both the provider catalog and the custom-voice settings invite the user to pick any Azure voice.

Steps to Reproduce

  1. Configure an Azure speech key and region.
  2. Select the Azure TTS provider.
  3. Set the voice to any non-Chinese voice, for example en-US-JennyNeural or en-ZA-LeahNeural.
  4. Generate narration.

Expected Behavior

Azure synthesises the selected voice and returns audio.

Actual Behavior

The request fails because the voice does not match the SSML language, and no audio is produced. Every non-Chinese voice is affected — this is not limited to any one language.

Deployment Method

Local development (npm run dev / pnpm dev / yarn dev)

OpenMAIC Version

1.0.1 (64621adf)

Affected Area

Model / provider integration

Browser

Not applicable

Operating System

Windows 11 (app served from WSL2)

Relevant Logs

bash
Azure TTS request failed: 400 — The language specified in the SSML is not supported
by the voice 'en-US-JennyNeural'.

Additional Context

The locale is derivable from the voice name, which is already in BCP-47 form: strip the trailing Neural/MultilingualNeural segment and keep the remainder.

typescript
const voiceSegments = (config.voice ?? '').split('-');
const voiceLocale = voiceSegments.length > 1 ? voiceSegments.slice(0, -1).join('-') : 'zh-CN';

This yields en-ZA-LeahNeuralen-ZA and sr-Latn-RS-SomeNeuralsr-Latn-RS. I have this working locally and am happy to open a PR if that would help.