{"record":{"id":"2e91f4bababdae65","repo":"danny-avila/LibreChat","slug":"invalid-provider-2e91f4","errorCode":null,"errorMessage":"Invalid provider","messagePattern":"Invalid provider","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/server/services/Files/Audio/TTSService.js","lineNumber":266,"sourceCode":"  }\n\n  /**\n   * Sends a TTS request to the specified provider.\n   * @async\n   * @param {string} provider - The TTS provider to use.\n   * @param {Object} ttsSchema - The TTS schema for the provider.\n   * @param {Object} options - The options for the TTS request.\n   * @param {string} options.input - The input text.\n   * @param {string} options.voice - The voice to use.\n   * @param {boolean} [options.stream=true] - Whether to use streaming.\n   * @param {string[]} [allowedAddresses] - Section-level SSRF exemption list of host:port pairs.\n   * @returns {Promise<Object>} The axios response object.\n   * @throws {Error} If the provider is invalid or the request fails.\n   */\n  async ttsRequest(provider, ttsSchema, { input, voice, stream = true }, allowedAddresses) {\n    const strategy = this.providerStrategies[provider];\n    if (!strategy) {\n      throw new Error('Invalid provider');\n    }\n\n    const [url, data, headers] = strategy.call(this, ttsSchema, input, voice, stream);\n\n    [data, headers].forEach(this.removeUndefined.bind(this));\n\n    const options = { headers, responseType: stream ? 'stream' : 'arraybuffer' };\n\n    applyAxiosProxyConfig(options, url);\n    applySSRFSafeAgentIfDirect(options, url, allowedAddresses);\n\n    try {\n      return await axios.post(url, data, options);\n    } catch (error) {\n      logAxiosError({ message: `TTS request failed for provider ${provider}:`, error });\n      throw error;\n    }\n  }","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/api/server/services/Files/Audio/TTSService.js#L248-L284","documentation":"ttsRequest looks up this.providerStrategies[provider]; if the provider string is not a registered strategy key (openai, azureOpenAI, elevenlabs, localai) it throws synchronously before forming the request. This prevents dispatching to an unimplemented strategy.","triggerScenarios":"The provider returned by getProvider (or passed directly) does not match a key in providerStrategies — e.g. casing mismatch, a constant value that drifted, or a provider configured with no strategy.","commonSituations":"librechat-data-provider TTSProviders constant changed value and the service wasn't updated; config hand-edited with a wrong provider string; new provider referenced before its strategy was implemented.","solutions":["Ensure the `speech.tts` provider key matches a supported TTSProviders constant exactly.","Confirm only one provider is configured so getProvider returns the right one.","Upgrade librechat-data-provider and the API service together so constant values and strategy keys agree."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"const { TTSProviders } = require('librechat-data-provider');\nif (!Object.values(TTSProviders).includes(provider)) {\n  throw new Error(`Unknown TTS provider: ${provider}`);\n}","typeGuard":"/** @param {string} p */\nfunction isValidTtsProvider(p) {\n  const { TTSProviders } = require('librechat-data-provider');\n  return Object.values(TTSProviders).includes(p);\n}","tryCatchPattern":null,"preventionTips":["Source provider names from TTSProviders constants, never literals.","Upgrade librechat-data-provider and the API service together.","Assert at startup that every providerStrategies key maps to a known constant."],"tags":["tts","provider","config","strategy"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}