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

  1. Dump the response HTML and inspect which of `FdrFJe` / `cfb2h` is missing and what the page actually contains
  2. Update the regexes/keys to the new page format, or pin to a maintained library (e.g. google-tts-api) that tracks these changes
  3. Bypass scraping by supplying static token values (bl is commonly a version like `boq_translate-webserver_...`; many clients hardcode a working bl)
  4. 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

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

Related errors


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