xtekky/gpt4free · error · ValueError

No voices found for language '{audio.get('language')}' and l

Error message

No voices found for language '{audio.get('language')}' and locale '{audio.get('locale')}'.

What it means

ValueError from EdgeTTS when no voice matched the requested language/locale after querying Microsoft's VoicesManager. The provider searches voices by audio['locale'], by audio['language'] (as locale if it contains '-', else as language), or falls back to the provider's default locale; an empty result means the combination doesn't exist in edge-tts's voice catalog.

Source

Thrown at g4f/Provider/audio/EdgeTTS.py:65

        **kwargs,
    ) -> AsyncResult:
        prompt = get_last_message(messages, prompt)
        if not prompt:
            raise ValueError("Prompt is empty.")
        voice = audio.get("voice", model if model and model != cls.model_id else None)
        if not voice:
            voices = await VoicesManager.create()
            if "locale" in audio:
                voices = voices.find(Locale=audio["locale"])
            elif audio.get("language", cls.default_language) != cls.default_language:
                if "-" in audio.get("language"):
                    voices = voices.find(Locale=audio.get("language"))
                else:
                    voices = voices.find(Language=audio.get("language"))
            else:
                voices = voices.find(Locale=cls.default_locale)
            if not voices:
                raise ValueError(
                    f"No voices found for language '{audio.get('language')}' and locale '{audio.get('locale')}'."
                )
            voice = random.choice(voices)["Name"]

        format = audio.get("format", cls.default_format)
        filename = get_filename([cls.model_id], prompt, f".{format}", prompt)
        target_path = os.path.join(get_media_dir(), filename)
        ensure_media_dir()

        extra_parameters = {
            param: audio[param]
            for param in ["rate", "volume", "pitch"]
            if param in audio
        }
        communicate = edge_tts.Communicate(
            prompt, voice=voice, proxy=proxy, **extra_parameters
        )

View on GitHub (pinned to 973504e177)

Solutions

  1. Use a valid BCP-47 locale from edge-tts's voice list (e.g. 'en-US', 'de-DE', 'hi-IN')
  2. Pass an explicit voice name in audio={'voice': 'en-US-AriaNeural'} to skip lookup
  3. List valid voices first: await edge_tts.VoicesManager.create() and inspect find() results
  4. Fix typos in locale/language codes

Example fix

# before
await client.speech.create(model='EdgeTTS', text='hi', audio={'language': 'en-USA'})

# after
await client.speech.create(model='EdgeTTS', text='hi', audio={'voice': 'en-US-AriaNeural'})
Defensive patterns

Strategy: validation

Validate before calling

import edge_tts

async def voice_exists(locale=None, language=None):
    vm = await edge_tts.VoicesManager.create()
    found = vm.find(Locale=locale) if locale else vm.find(Language=language)
    return bool(found)

# or validate a fixed allowlist: {'en-US', 'de-DE', 'hi-IN', ...}

Type guard

import re

def is_valid_locale(code: str) -> bool:
    return bool(re.fullmatch(r'[a-z]{2,3}-[A-Z]{2}(?:[A-Z]{2})?', code or ''))

Try / catch

try:
    ...  # speech call with language
except ValueError as e:
    if 'No voices found' in str(e):
        retry with audio={'voice': 'en-US-AriaNeural'}  # known-good default

Prevention

When it happens

Trigger: Passing audio={'voice': None, 'language': 'xx'} or audio={'locale': 'xx-XX'} for an unsupported language/region; also defaulting paths when the voices list couldn't load matching entries.

Common situations: Requests for languages edge-tts doesn't ship (e.g. constructed or very rare locale codes); typos like 'en-USA' instead of 'en-US'; mismatched pairs like language='fr' with locale='de-DE'.

Related errors


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/0e28a33128e76544. Report an issue: GitHub.