{"record":{"id":"dd49714b9a5bb225","repo":"decolua/9router","slug":"self-hosted-tts-failed-res-status","errorCode":null,"errorMessage":"Self-hosted TTS failed: ${res.status}","messagePattern":"Self-hosted TTS failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"open-sse/handlers/ttsProviders/selfhostedTts.js","lineNumber":64,"sourceCode":"      }\n    }\n\n    const res = await fetch(`${base}/v1/audio/speech`, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        ...(credentials?.apiKey ? { Authorization: `Bearer ${credentials.apiKey}` } : {}),\n      },\n      body: JSON.stringify({\n        model: ttsModel,\n        voice,\n        input: text,\n        response_format: responseFormat,\n      }),\n    });\n    if (!res.ok) {\n      const err = await res.json().catch(() => ({}));\n      throw new Error(err?.error?.message || `Self-hosted TTS failed: ${res.status}`);\n    }\n    const buf = await res.arrayBuffer();\n    return { base64: Buffer.from(buf).toString(\"base64\"), format: responseFormat };\n  },\n};\n","sourceCodeStart":46,"sourceCodeEnd":70,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/handlers/ttsProviders/selfhostedTts.js#L46-L70","documentation":"Thrown when a self-hosted OpenAI-compatible TTS server (e.g. local Kokoro/Faster-Whisper style /v1/audio/speech) returns a non-2xx status. The handler prefers a JSON error.message from the body, falling back to this status-code template. It reflects your own server's rejection, not a cloud provider.","triggerScenarios":"POST to the configured self-hosted base URL fails: server not fully started, wrong port/path, model not loaded on the server, unsupported response_format requested, or an auth middleware rejecting the request.","commonSituations":"Docker container still loading the model (503), reverse proxy returning 404/502, requesting a response_format the server doesn't implement, or firewall/local network issues producing 5xx from a proxy.","solutions":["Check the HTTP status: 404 -> wrong base URL/path, 503 -> server still loading or down, 401 -> auth required","Confirm the TTS server is running and the model is loaded (hit its health/docs endpoint)","Verify base URL, port, and API version path in the 9Router provider config","Request a response_format the server supports (e.g. mp3/wav)","Inspect the self-hosted server logs for the underlying error"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const health = await fetch(`${baseUrl}/v1/models`).catch(() => null);\nif (!health || !health.ok) throw new Error(`Self-hosted TTS unreachable at ${baseUrl}`);","typeGuard":"function isSelfHostedHttpError(e) {\n  return e instanceof Error && /^Self-hosted TTS failed: \\d{3}$/.test(e.message);\n}","tryCatchPattern":"try {\n  return await selfHostedTts.synthesize(text, model, opts);\n} catch (e) {\n  const m = e.message.match(/Self-hosted TTS failed: (\\d{3})/);\n  if (m && m[1] === \"503\") return retryWithBackoff(() => selfHostedTts.synthesize(text, model, opts)); // server warming up\n  throw e;\n}","preventionTips":["Add a startup health probe against the self-hosted /v1/models endpoint","Use a documented response_format the server actually supports","Put the TTS server behind a stable internal hostname, not localhost inside containers","Watch server logs and readiness endpoints before routing traffic"],"tags":["tts","self-hosted","http-error","network"],"backgroundTag":"upstream-http-error","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}