{"record":{"id":"224074f273281204","repo":"moeru-ai/airi","slug":"internal-server-error","errorCode":"INTERNAL_SERVER_ERROR","errorMessage":"${providerLabel} tts fetch failed: ${errorMessageFrom(error) ?? 'unknown'}","messagePattern":"(.+?) tts fetch failed: (.+?)","errorType":"exception","errorClass":"ApiError","httpStatus":500,"severity":"error","filePath":"server/apps/api/src/services/adapters/tts/unspeech.ts","lineNumber":82,"sourceCode":"    return {\n      contentType: result.contentType ?? fallbackContentType,\n      body: result.body,\n    }\n  }\n  catch (error) {\n    // Keep abort identity intact so the router can apply `onTimeout`\n    // independently from HTTP 500 fallback policy.\n    if (ctx.abortSignal?.aborted)\n      throw error\n\n    if (error instanceof UnSpeechAPIError) {\n      throw new TtsUpstreamResponseError(new Response(error.responseBody, {\n        status: error.status,\n        headers: error.responseHeaders,\n      }))\n    }\n\n    throw createInternalError(`${providerLabel} tts fetch failed: ${errorMessageFrom(error) ?? 'unknown'}`)\n  }\n}\n\ninterface ListVoicesOptions {\n  ctx: TtsVoiceCatalogContext\n  query: string\n  providerLabel: string\n}\n\n/**\n * Lists unspeech voices and maps SDK failures into AIRI gateway errors.\n *\n * Use when:\n * - A TTS adapter needs unspeech's normalized `Voice[]` catalog.\n *\n * Expects:\n * - `query` is an unspeech `/api/voices` query string such as\n *   `provider=microsoft&region=eastasia`.","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/moeru-ai/airi/blob/f679616c34f1cf6d282c8d64264242af944b3fed/server/apps/api/src/services/adapters/tts/unspeech.ts#L64-L100","documentation":"Catch-all in sendSpeechViaUnSpeech: the proxied TTS fetch through the UnSpeech upstream failed with an unexpected error that is neither an abort nor an UnSpeechAPIError (e.g. network failure, DNS error, connection reset). The error is rewrapped as an internal error with the provider label and extracted message so the router sees a single failure record; HTTP-level failures are handled separately as TtsUpstreamResponseError and aborts are rethrown untouched.","triggerScenarios":"Thrown at server/apps/api/src/services/adapters/tts/unspeech.ts:82 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check upstream TTS provider connectivity, DNS, and TLS from the server","Verify provider credentials and base URL configuration for the labeled provider","Use errorMessageFrom(error) output in the message to identify the underlying network/library failure"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f679616c34f1cf6d282c8d64264242af944b3fed","analyzedAt":"2026-09-08T13:18:15.005Z","contentChangedAt":"2026-09-08T13:18:15.005Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}