decolua/9router · error
Bing TTS returned empty audio
Error message
Bing TTS returned empty audio
What it means
After Bing's tfettts endpoint responds 200, edgeTts.js reads the body and requires at least 1024 bytes before treating it as valid MP3 audio; a smaller payload throws "Bing TTS returned empty audio". This guards against responses that look successful but contain no usable audio (error pages, empty bodies, stub responses from the undocumented endpoint).
Source
Thrown at open-sse/handlers/ttsProviders/edgeTts.js:86
async synthesize(text, model) {
const voiceId = model || "vi-VN-HoaiMyNeural";
let token = await getToken();
let res = await ttsRequest(text, voiceId, token);
// 429/403: invalidate cache and retry once
if (res.status === 429 || res.status === 403) {
cache.token = null;
cache.tokenTime = 0;
token = await getToken();
res = await ttsRequest(text, voiceId, token);
}
if (!res.ok) {
const body = await res.text().catch(() => "");
throw new Error(`Bing TTS failed: ${res.status}${body ? " - " + body : ""}`);
}
const buf = await res.arrayBuffer();
if (buf.byteLength < 1024) throw new Error("Bing TTS returned empty audio");
return { base64: Buffer.from(buf).toString("base64"), format: "mp3" };
},
};
View on GitHub (pinned to 90b52e06ff)
Solutions
- Verify the voice id is real by fetching the voice list (fetchEdgeTtsVoices) and picking one of its `ShortName` values instead of a hand-typed id.
- Check that the text argument is non-empty and non-whitespace before calling synthesize; log the text length when this fires.
- Retry the request — this is often transient; the module refreshes its Bing token every ~5 minutes, so a later attempt may use a fresh token.
- Inspect the actual response: temporarily log res body/headers on this path; if Bing consistently returns HTML instead of audio, its endpoint changed and this provider needs updating or replacing.
- Fall back to another TTS provider for affected requests.
Example fix
// before
text = userInput.trim();
await edgeTts.synthesize(text, "my-custom-voice");
// after: validate inputs against the real voice list
const voices = await fetchEdgeTtsVoices();
const voice = "my-custom-voice";
if (!text?.trim()) throw new Error("TTS text is empty");
if (!voices.some(v => v.ShortName === voice)) throw new Error(`Unknown voice: ${voice}`);
await edgeTts.synthesize(text.trim(), voice); Defensive patterns
Strategy: validation
Validate before calling
import { fetchEdgeTtsVoices } from "open-sse/handlers/ttsProviders/edgeTts.js";
if (!text?.trim()) throw new Error("TTS text is empty");
const voices = await fetchEdgeTtsVoices();
if (!voices.some(v => v.ShortName === voiceId)) throw new Error(`Unknown Edge voice: ${voiceId}`); Type guard
function isValidEdgeVoice(voice, voices) {
return typeof voice === "string" && voices.some(v => v.ShortName === voice);
} Try / catch
try {
const audio = await edgeTts.synthesize(text, voiceId);
} catch (e) {
if (e.message === "Bing TTS returned empty audio") {
// usually invalid voice or empty text — retry once with a known-good default voice
return edgeTts.synthesize(text, "en-US-AriaNeural");
}
throw e;
} Prevention
- Always pick voice ids from fetchEdgeTtsVoices() rather than hand-typing them.
- Reject empty/whitespace text at the API boundary.
- Retry once on this error before surfacing it — it is often transient.
- If it becomes consistent, suspect a Bing endpoint/format change and check for library updates.
When it happens
Trigger: The Bing TTS endpoint returns HTTP 200 but a tiny body — typically when Bing silently rejects the SSML/token (returns an empty or stub response), the requested voiceId is invalid/unsupported, the text is empty or only whitespace, or Bing returns an HTML error page smaller than 1KB with a 200 status.
Common situations: Passing a made-up or removed voice id (e.g. "xx-YY-FooNeural") that Bing accepts but cannot synthesize; sending empty text after client-side trimming; Bing A/B-testing a new response format that no longer returns MP3; intermittent Bing flakiness where the endpoint 200s with an empty body.
Related errors
- ElevenLabs TTS returned empty audio
- Upstream returned empty audio
- Bing TTS failed: ${res.status}${body ? " - " + body : ""}
- ElevenLabs voices fetch failed: ${res.status}
- ElevenLabs TTS failed: ${res.status}
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/ff9ff6697e90e08c.
Report an issue: GitHub.