{"record":{"id":"815613750606c4bb","repo":"moeru-ai/airi","slug":"openrouter-audio-request-failed-response-status-815613","errorCode":null,"errorMessage":"OpenRouter audio request failed: ${response.status} ${await response.text()}","messagePattern":"OpenRouter audio request failed: (.+?) (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/provider-inference/src/providers/cloud/openrouter-audio-speech/index.ts","lineNumber":114,"sourceCode":"\n    const body = JSON.parse(init.body) as { input?: string, voice?: string }\n    const response = await globalThis.fetch(new URL('chat/completions', baseUrl), {\n      method: 'POST',\n      headers: {\n        'Authorization': `Bearer ${apiKey}`,\n        'Content-Type': 'application/json',\n        ...OPENROUTER_ATTRIBUTION_HEADERS,\n      },\n      body: JSON.stringify({\n        model,\n        messages: [{ role: 'user', content: ttsPrompt(body.input ?? '') }],\n        modalities: ['text', 'audio'],\n        audio: { voice: body.voice, format: 'pcm16' },\n        stream: true,\n      }),\n    })\n    if (!response.ok)\n      throw new Error(`OpenRouter audio request failed: ${response.status} ${await response.text()}`)\n    if (!response.body)\n      throw new Error('OpenRouter audio response has no body')\n\n    const wav = toWavFromPCM16(decodeBase64Pcm(await collectAudioChunks(response.body)), 24000)\n    return new Response(new Blob([wav], { type: 'audio/wav' }), {\n      status: 200,\n      headers: { 'Content-Type': 'audio/wav' },\n    })\n  }\n}\n\nexport const providerOpenRouterAudioSpeech = defineProvider<OpenRouterAudioConfig, 'openrouter-audio-speech'>({\n  id: 'openrouter-audio-speech',\n  name: 'OpenRouter',\n  nameLocalize: ({ t }) => t('settings.pages.providers.provider.openrouter-audio-speech.title'),\n  description: 'openrouter.ai',\n  descriptionLocalize: ({ t }) => t('settings.pages.providers.provider.openrouter-audio-speech.description'),\n  tasks: ['text-to-speech'],","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/moeru-ai/airi/blob/f679616c34f1cf6d282c8d64264242af944b3fed/packages/provider-inference/src/providers/cloud/openrouter-audio-speech/index.ts#L96-L132","documentation":"The OpenRouter adapter posts to OpenRouter's chat/completions with modalities ['text','audio'] and streaming enabled. If OpenRouter returns a non-ok HTTP response, the status and the raw response text (which holds OpenRouter's error JSON) are thrown as this error. It is an upstream API failure.","triggerScenarios":"OpenRouter returns 401 (invalid key/credits), 404 (model doesn't support audio output), 400 (invalid voice or modality combination), 402 (insufficient credits), 429 (rate limit), or 5xx.","commonSituations":"Selected model lacks audio output support; voice id not supported by the routed model; exhausted OpenRouter credits; wrong API key; model provider outage.","solutions":["Read the error text — it contains OpenRouter's error message (e.g. 'no audio capable model found').","Choose a model that supports audio output (audio in modalities) on OpenRouter.","Verify the OpenRouter API key and remaining credits.","Check that the requested voice is supported by the routed model.","Retry with backoff on 429/5xx."],"exampleFix":"// before\nconst model = 'openai/gpt-4o-mini' // no audio output support\n// after\nconst model = 'openai/gpt-4o-audio-preview' // audio-capable model","handlingStrategy":"try-catch","validationCode":"if (!openRouterApiKey) throw new Error('OpenRouter API key required')\nif (!audioCapableModel) throw new Error('Selected model must support audio output')","typeGuard":null,"tryCatchPattern":"try { await speak(text) } catch (e) {\n  if (/failed: 4\\d\\d/.test(e.message)) showUpstreamError(e.message) // includes OpenRouter error JSON\n  if (/failed: (429|5\\d\\d)/.test(e.message)) await backoffRetry()\n}","preventionTips":["Pick models explicitly supporting audio output","Keep OpenRouter credits funded","Log the embedded response text for diagnostics","Handle 429 with retry/backoff"],"tags":["network","http","upstream-api","tts"],"backgroundTag":"upstream-api-error","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"}