decolua/9router · error · Error
Failed to parse Google token
Error message
Failed to parse Google token
What it means
After fetching the Google Translate page, the code scrapes two values from inline JS via regex: `"FdrFJe":"..."` (f.sid) and `"cfb2h":"..."` (bl). If either regex fails to match, it throws this error. It indicates the page HTML no longer contains the expected token fields — the unofficial scraping contract broke.
Source
Thrown at open-sse/handlers/ttsProviders/googleTts.js:16
// Google Translate TTS (no auth) — scrape token + batchexecute RPC
import { UA } from "./_base.js";
const REFRESH_MS = 11 * 60 * 1000;
const cache = { token: null, tokenTime: 0 };
let _idx = 0;
async function getToken() {
const now = Date.now();
if (cache.token && now - cache.tokenTime < REFRESH_MS) return cache.token;
const res = await fetch("https://translate.google.com/", { headers: { "User-Agent": UA } });
if (!res.ok) throw new Error(`Google translate fetch failed: ${res.status}`);
const html = await res.text();
const fSid = html.match(/"FdrFJe":"(.*?)"/)?.[1];
const bl = html.match(/"cfb2h":"(.*?)"/)?.[1];
if (!fSid || !bl) throw new Error("Failed to parse Google token");
cache.token = { "f.sid": fSid, bl };
cache.tokenTime = now;
return cache.token;
}
export default {
noAuth: true,
async synthesize(text, model) {
const lang = model || "en";
const token = await getToken();
const cleanText = text.replace(/[@^*()\\/\-_+=><"'\u201c\u201d\u3010\u3011]/g, " ").replaceAll(", ", ". ");
const rpcId = "jQ1olc";
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,View on GitHub (pinned to 90b52e06ff)
Solutions
- Dump the response HTML and inspect which of `FdrFJe` / `cfb2h` is missing and what the page actually contains
- Update the regexes/keys to the new page format, or pin to a maintained library (e.g. google-tts-api) that tracks these changes
- Bypass scraping by supplying static token values (bl is commonly a version like `boq_translate-webserver_...`; many clients hardcode a working bl)
- Route via a residential IP / add cookies to avoid challenge pages
Example fix
// before
const fSid = html.match(/"FdrFJe":"(.*?)"/)?.[1];
const bl = html.match(/"cfb2h":"(.*?)"/)?.[1];
if (!fSid || !bl) throw new Error('Failed to parse Google token');
// after (fallback to known-good static bl)
const bl = html.match(/"cfb2h":"(.*?)"/)?.[1] || 'boq_translate-webserver_20240101.00_p0';
const fSid = html.match(/"FdrFJe":"(.*?)"/)?.[1] || '-1'; Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
const token = { fSid: html?.match(/"FdrFJe":"(.*?)"/)?.[1], bl: html?.match(/"cfb2h":"(.*?)"/)?.[1] }; Try / catch
try { return await googleTts(text); } catch (e) { if (e.message === 'Failed to parse Google token') return otherProviderTts(text); throw e; } Prevention
- Assume the scraping contract can break any time; never let Google-translate TTS be the only TTS path
- Test the regex extraction in CI against a live page fetch to detect Google UI changes
- Cache the last known-good token and reuse it when scraping fails
When it happens
Trigger: A 200 response whose body is a consent page, bot-check/CAPTCHA page, or a redesigned translate.google.com UI without those keys; gzip/compressed body not decoded; localized or A/B variants of the page.
Common situations: Google frontend update renaming the obfuscated keys (FdrFJe/cfb2h); bot mitigation serving challenge HTML to datacenter IPs; region-specific consent interstitials; a proxy stripping or transforming the HTML.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Google TTS returned empty audio
- Failed to parse Bing token
- Google translate fetch failed: ${res.status}
- Google TTS failed: ${res.status}
- Upstream returned empty audio
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/60e130e4a049ae05.
Report an issue: GitHub.