ChatGPTNextWeb/NextChat · error · Error
Could not infer voiceLocale from voiceName!
Error message
Could not infer voiceLocale from voiceName!
What it means
Thrown at app/utils/ms_edge_tts.ts:296 inside setMetadata when voiceLocale is not supplied and the voiceName fails to match VOICE_LANG_REGEX (=/\w{2}-\w{2}/). The regex extracts a locale like 'en-US' from a ShortName voice such as 'en-US-AriaNeural'; if the voiceName lacks that 'XX-XX' locale segment, inference fails and synthesis cannot proceed because the SSML xml:lang would be empty.
Source
Thrown at app/utils/ms_edge_tts.ts:296
* @param voiceName a string with any `ShortName`. A list of all available neural voices can be found [here](https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support#neural-voices). However, it is not limited to neural voices: standard voices can also be used. A list of standard voices can be found [here](https://docs.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support#standard-voices)
* @param outputFormat any {@link OUTPUT_FORMAT}
* @param voiceLocale (optional) any voice locale that is supported by the voice. See the list of all voices for compatibility. If not provided, the locale will be inferred from the `voiceName`
*/
async setMetadata(
voiceName: string,
outputFormat: OUTPUT_FORMAT,
voiceLocale?: string,
) {
const oldVoice = this._voice;
const oldVoiceLocale = this._voiceLocale;
const oldOutputFormat = this._outputFormat;
this._voice = voiceName;
this._voiceLocale = voiceLocale;
if (!this._voiceLocale) {
const voiceLangMatch = MsEdgeTTS.VOICE_LANG_REGEX.exec(this._voice);
if (!voiceLangMatch)
throw new Error("Could not infer voiceLocale from voiceName!");
this._voiceLocale = voiceLangMatch[0];
}
this._outputFormat = outputFormat;
const changed =
oldVoice !== this._voice ||
oldVoiceLocale !== this._voiceLocale ||
oldOutputFormat !== this._outputFormat;
// create new client
if (changed || this._ws!.readyState !== this._ws!.OPEN) {
this._startTime = Date.now();
await this._initClient();
}
}
private _metadataCheck() {
if (!this._ws)View on GitHub (pinned to defdcdb55d)
Solutions
- Always pass an official ShortName (e.g. 'en-US-AriaNeural') obtained from getVoices().
- Pass an explicit voiceLocale argument to setMetadata so inference is not relied upon.
- Validate voiceName against /\w{2}-\w{2}/ before calling setMetadata and warn the user early.
- If supporting non-ShortName voices, build a voiceName->locale lookup from the voices list and look it up instead of regex inference.
Example fix
// before
await tts.setMetadata('Aria', OUTPUT_FORMAT.AUDIO_24KHZ_48KBITRATE_MONO_MP3);
// after
const voiceName = 'en-US-AriaNeural';
await tts.setMetadata(
voiceName,
OUTPUT_FORMAT.AUDIO_24KHZ_48KBITRATE_MONO_MP3,
'en-US', // explicit locale, no inference needed
); Defensive patterns
Strategy: validation
Validate before calling
const VOICE_LOCALE_RE = /\w{2}-\w{2}/;
function canInferLocale(voiceName: string): boolean {
return VOICE_LOCALE_RE.test(voiceName);
}
if (!canInferLocale(voiceName)) {
throw new Error(
`voiceName "${voiceName}" has no locale segment; pass an explicit voiceLocale`,
);
}
await tts.setMetadata(voiceName, outputFormat); Type guard
function isShortNameVoice(name: string): boolean {
// ShortName format: <locale>-<VoiceName>Neural, e.g. en-US-AriaNeural
return /^\w{2}-\w{2}-\w+Neural$/.test(name);
} Try / catch
try {
await tts.setMetadata(voiceName, outputFormat);
} catch (e) {
if (e instanceof Error && /infer voiceLocale/.test(e.message)) {
await tts.setMetadata(voiceName, outputFormat, "en-US"); // explicit fallback locale
} else {
throw e;
}
} Prevention
- Always source voiceName from getVoices() output rather than hard-coding it.
- Pass an explicit voiceLocale to setMetadata to skip regex inference entirely.
- Validate the ShortName format before offering it as a selectable voice.
When it happens
Trigger: Passing a voiceName with no locale segment (e.g. 'Aria', 'MyCustomVoice', or a malformed/empty string); passing a voiceName with an uppercase country-only or language-only segment that does not match the two-letter-two-letter pattern; passing a LongName or multilingual voice id whose format differs from ShortName.
Common situations: Hard-coding a voice display name instead of its ShortName; user types a custom voice string in settings; voice list loaded from a different/older source whose names don't include the locale; passing undefined/'' accidentally.
Related errors
AI-assisted analysis of ChatGPTNextWeb/NextChat@defdcdb55d (2026-08-12).
Data as JSON: /api/errors/681a47bdc1c84c9c.
Report an issue: GitHub.