decolua/9router · error · Error

Google TTS failed: ${res.status}

Error message

Google TTS failed: ${res.status}

What it means

The synthesize function POSTs an RPC batchexecute request to translate.google.com to get MP3 audio. Non-2xx responses throw this error with the upstream HTTP status. Since this is an undocumented internal Google RPC endpoint, non-200s usually mean the request/token is stale or blocked.

Source

Thrown at open-sse/handlers/ttsProviders/googleTts.js:47

    const reqId = (++_idx * 100000) + Math.floor(1000 + Math.random() * 9000);
    const query = new URLSearchParams({
      rpcids: rpcId,
      "f.sid": token["f.sid"],
      bl: token.bl,
      hl: lang,
      "soc-app": 1, "soc-platform": 1, "soc-device": 1,
      _reqid: reqId,
      rt: "c",
    });
    const payload = [cleanText, lang, null, "undefined", [0]];
    const body = new URLSearchParams();
    body.append("f.req", JSON.stringify([[[rpcId, JSON.stringify(payload), null, "generic"]]]));
    const res = await fetch(`https://translate.google.com/_/TranslateWebserverUi/data/batchexecute?${query}`, {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded", "Referer": "https://translate.google.com/" },
      body: body.toString(),
    });
    if (!res.ok) throw new Error(`Google TTS failed: ${res.status}`);
    const data = await res.text();
    const split = JSON.parse(data.split("\n")[3]);
    const base64 = JSON.parse(split[0][2])[0];
    if (!base64 || base64.length < 100) throw new Error("Google TTS returned empty audio");
    return { base64, format: "mp3" };
  },
};

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Invalidate the token cache and refetch (fix the scraper/token) so batchexecute runs with fresh f.sid/bl
  2. Confirm headers: `Content-Type: application/x-www-form-urlencoded` and `Referer: https://translate.google.com/` must be present
  3. Check the status code in the message: 429 → backoff/IP rotation; 400 → inspect the f.req payload against current schema
  4. Switch to an official TTS provider or maintained google-tts-api library for reliability
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

try { return await googleTts.synthesize(text); } catch (e) { const m = e.message.match(/Google TTS failed: (\d+)/); if (m && (m[1] === '429' || m[1].startsWith('5'))) { await sleep(expBackoff()); return retryOnce(); } throw e; }

Prevention

When it happens

Trigger: batchexecute returns 4xx/5xx: expired/invalid `f.sid`/`bl` token in the query, missing/bad Referer, rate limiting (429), or Google blocking the internal RPC for the client IP.

Common situations: Long-lived process using a token scraped hours ago that Google invalidated; datacenter IP blocked; malformed f.req after a payload schema change (surfacing as 400).

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/ecb9086a2d9250c2. Report an issue: GitHub.