zeroclaw-labs/zeroclaw · error

Google TTS API error ({}): {}

Error message

Google TTS API error ({}): {}

What it means

Raised by GoogleTtsProvider::synthesize when POST https://texttospeech.googleapis.com/v1/text:synthesize returns non-2xx. The key travels in the x-goog-api-key header from [providers.tts.google.<alias>].api_key. Note the body is parsed as JSON first (a non-JSON body fails earlier with "Failed to parse Google TTS response"), then error.message is extracted, so this message means Google answered with a structured API error.

Source

Thrown at crates/zeroclaw-channels/src/tts.rs:368

            .client
            .post(url)
            .header("x-goog-api-key", &self.api_key)
            .json(&body)
            .send()
            .await
            .context("Failed to send Google TTS request")?;

        let status = resp.status();
        let resp_body: serde_json::Value = resp
            .json()
            .await
            .context("Failed to parse Google TTS response")?;

        if !status.is_success() {
            let msg = resp_body["error"]["message"]
                .as_str()
                .unwrap_or("unknown error");
            bail!("Google TTS API error ({}): {}", status, msg);
        }

        let audio_b64 = resp_body["audioContent"]
            .as_str()
            .context("Google TTS response missing 'audioContent' field")?;

        use base64::Engine;
        let bytes = base64::engine::general_purpose::STANDARD
            .decode(audio_b64)
            .context("Failed to decode Google TTS base64 audio")?;
        Ok(bytes)
    }

    fn supported_voices(&self) -> Vec<String> {
        // Google voices vary by language; return common English defaults.
        [
            "en-US-Standard-A",
            "en-US-Standard-B",

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. For 403 SERVICE_DISABLED, enable "Cloud Text-to-Speech API" in the GCP console for the key's project and enable billing.
  2. For 403 API_KEY_INVALID, fix [providers.tts.google.<alias>].api_key (env grammar ZEROCLAW_providers__tts__google__<alias>__api_key).
  3. For 400 voice/language messages, make voice and language_code agree, e.g. language_code = "en-US" with voice = "en-US-Standard-A", or switch to the en-GB voice set.
  4. For quota messages, raise the quota or back off; the built-in client already caps calls at 60s.

Example fix

# before — voice language does not match language_code
[providers.tts.google.main]
api_key = "AIza..."
language_code = "en-US"
voice = "en-GB-Standard-A"

# after
[providers.tts.google.main]
api_key = "AIza..."
language_code = "en-US"
voice = "en-US-Standard-A"
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: voice name must match its language prefix.
fn voice_matches_language(voice: &str, language_code: &str) -> bool {
    // voice names look like "en-US-Standard-A" / "en-US-Neural2-F"
    let prefix: String = language_code.chars().take_while(|c| c.is_ascii_alphanumeric() || *c == '-').collect();
    voice.starts_with(&prefix)
}

assert!(voice_matches_language(voice, "en-US"));

Try / catch

match mgr.synthesize(text).await {
    Ok(audio) => Ok(audio),
    Err(err) if err.to_string().contains("Google TTS API error (403)") => {
        Err(err.context("enable Cloud Text-to-Speech API / check api_key"))
    }
    Err(err) if err.to_string().contains("(429)") => {
        tokio::time::sleep(Duration::from_secs(2)).await;
        mgr.synthesize(text).await
    }
    Err(err) => Err(err),
}

Prevention

When it happens

Trigger: 403 with API_KEY_INVALID or SERVICE_DISABLED (Cloud Text-to-Speech API not enabled on the project), 400 when the voice name does not match language_code (default en-US, e.g. voice en-GB-Standard-A with en-US), 400 for a malformed language_code, and 429/403 for quota or billing not enabled.

Common situations: The key exists but the Text-to-Speech API was never enabled in the GCP console. Copying a voice name from another language's docs while language_code stays en-US. Using a browser-API key restricted to different services.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/cd02d5de2f6e81ed. Report an issue: GitHub.