{"record":{"id":"e6bec3584f938894","repo":"decolua/9router","slug":"bing-translator-fetch-failed-res-status","errorCode":null,"errorMessage":"Bing translator fetch failed: ${res.status}","messagePattern":"Bing translator fetch failed: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"open-sse/handlers/ttsProviders/edgeTts.js","lineNumber":18,"sourceCode":"// Microsoft Edge / Bing TTS (no auth) — via Bing translator endpoint\nimport { Buffer } from \"node:buffer\";\nimport { UA } from \"./_base.js\";\n\nconst REFRESH_MS = 5 * 60 * 1000; // token TTL ~1h, refresh early\nconst VOICES_TTL = 24 * 60 * 60 * 1000;\n\nconst cache = { token: null, tokenTime: 0 };\nlet _voicesCache = null;\nlet _voicesCacheTime = 0;\n\nasync function getToken() {\n  const now = Date.now();\n  if (cache.token && now - cache.tokenTime < REFRESH_MS) return cache.token;\n  const res = await fetch(\"https://www.bing.com/translator\", {\n    headers: { \"User-Agent\": UA, \"Accept-Language\": \"vi,en-US;q=0.9,en;q=0.8\" },\n  });\n  if (!res.ok) throw new Error(`Bing translator fetch failed: ${res.status}`);\n  const rawCookies = res.headers.getSetCookie?.() || [];\n  const cookie = rawCookies.map((c) => c.split(\";\")[0]).join(\"; \");\n  const html = await res.text();\n  const match = html.match(/params_AbusePreventionHelper\\s*=\\s*\\[([^,]+),([^,]+),/);\n  if (!match) throw new Error(\"Failed to parse Bing token\");\n  cache.token = { key: match[1], token: match[2].replace(/\"/g, \"\"), cookie };\n  cache.tokenTime = now;\n  return cache.token;\n}\n\nasync function ttsRequest(text, voiceId, token) {\n  const parts = voiceId.split(\"-\");\n  const xmlLang = parts.slice(0, 2).join(\"-\");\n  const gender = voiceId.toLowerCase().includes(\"male\") ? \"Male\" : \"Female\";\n  const ssml = `<speak version='1.0' xml:lang='${xmlLang}'><voice xml:lang='${xmlLang}' xml:gender='${gender}' name='${voiceId}'><prosody rate='0.00%'>${text}</prosody></voice></speak>`;\n  const body = new URLSearchParams();\n  body.append(\"ssml\", ssml);\n  body.append(\"token\", token.token);","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/handlers/ttsProviders/edgeTts.js#L1-L36","documentation":"edgeTts getToken() scrapes https://www.bing.com/translator to extract the params_AbusePreventionHelper token and cookies used for Edge TTS synthesis. When the initial fetch returns a non-2xx status, it throws 'Bing translator fetch failed: <status>'. Both token() and synthesize() depend on this, so all Edge TTS synthesis fails until a valid token is obtained.","triggerScenarios":"bing.com/translator returns 403/429/5xx: datacenter IP blocked or rate-limited by Bing bot detection, region-locked responses, network/proxy failure, or Bing changing/throttling the endpoint.","commonSituations":"Running the gateway on a cloud server/VPS whose IP range Bing blocks (very common — residential IPs work, datacenter IPs get 403); running behind a corporate proxy that intercepts the request; too-frequent synthesis triggering rate limiting; Bing A/B testing changes the page and later breaks token parsing too.","solutions":["Retry after a delay — transient 429/5xx clears on its own; add exponential backoff","Check if your server IP is blocked: curl -I https://www.bing.com/translator from the host; a 403 means IP-level blocking","Route outbound traffic through a residential proxy or run the gateway on a different network","Set a realistic browser User-Agent / include cookies if the default UA is being rejected","Fall back to another TTS provider (the repo's other ttsProviders) when Edge TTS is unavailable"],"exampleFix":"// before\nconst token = await edgeTts.synthesize(text, voice);\n// after\ntry {\n  const token = await edgeTts.synthesize(text, voice);\n} catch (e) {\n  if (String(e.message).includes(\"Bing translator fetch failed\")) {\n    return fallbackProvider.synthesize(text, voice); // e.g. another ttsProvider\n  }\n  throw e;\n}","handlingStrategy":"retry","validationCode":"const pre = await fetch(\"https://www.bing.com/translator\", { method: \"HEAD\" }).catch(() => null);\nif (!pre || !pre.ok) console.warn(\"Bing translator unreachable from this host — Edge TTS will fail\");","typeGuard":null,"tryCatchPattern":"try {\n  const audio = await edgeTts.synthesize(text, voice);\n} catch (e) {\n  if (String(e.message).startsWith(\"Bing translator fetch failed\")) {\n    await sleep(backoff); return edgeTts.synthesize(text, voice); // or fallback provider\n  }\n  throw e;\n}","preventionTips":["Prefer running Edge TTS from residential networks — datacenter IPs are frequently 403'd by Bing","Implement exponential backoff with jitter for 429/5xx","Keep another TTS provider configured as a fallback","Cache synthesized audio to reduce Bing request volume"],"tags":["tts","network","edge-tts","bing","rate-limit"],"backgroundTag":"http-403-forbidden","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}