{"record":{"id":"66813e84d7504ad8","repo":"decolua/9router","slug":"no-openai-api-key-configured","errorCode":null,"errorMessage":"No OpenAI API key configured","messagePattern":"No OpenAI API key configured","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"open-sse/handlers/ttsProviders/openai.js","lineNumber":9,"sourceCode":"// OpenAI TTS — model format: \"tts-model/voice\"\nimport { Buffer } from \"node:buffer\";\nimport { PROVIDER_MEDIA } from \"../../providers/index.js\";\n\nconst DEFAULT_TTS_MODEL = PROVIDER_MEDIA[\"openai\"]?.ttsConfig?.defaultModel;\n\nexport default {\n  async synthesize(text, model, credentials) {\n    if (!credentials?.apiKey) throw new Error(\"No OpenAI API key configured\");\n\n    let ttsModel = DEFAULT_TTS_MODEL;\n    let voice = \"alloy\";\n    if (model && model.includes(\"/\")) {\n      const parts = model.split(\"/\");\n      if (parts.length === 2) [ttsModel, voice] = parts;\n    } else if (model) {\n      voice = model;\n    }\n\n    const baseUrl = (credentials.baseUrl || \"https://api.openai.com\").replace(/\\/+$/, \"\");\n    const res = await fetch(`${baseUrl}/v1/audio/speech`, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\", \"Authorization\": `Bearer ${credentials.apiKey}` },\n      body: JSON.stringify({ model: ttsModel, voice, input: text }),\n    });\n    if (!res.ok) {\n      const err = await res.json().catch(() => ({}));","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/handlers/ttsProviders/openai.js#L1-L27","documentation":"The OpenAI TTS provider requires an apiKey in the credentials object passed to synthesize(). If credentials are missing or credentials.apiKey is falsy, it fails fast before making any HTTP call. This is a local configuration check, not an upstream error.","triggerScenarios":"Calling the OpenAI TTS synthesize flow without configuring an OpenAI API key in 9Router's account/credential store, or with a credential entry whose apiKey field is empty/undefined.","commonSituations":"Fresh installs where the OpenAI provider was selected for TTS but no key was added; keys deleted from the dashboard; passing the wrong provider's credentials object; env var not loaded.","solutions":["Add an OpenAI API key in the 9Router dashboard (provider credential settings)","Verify the credential record persisted and its apiKey field is non-empty","Restart the gateway after adding credentials so the account cache refreshes","Select a TTS provider that does have credentials configured"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!credentials?.apiKey) throw new Error(\"Configure an OpenAI API key before using OpenAI TTS\");","typeGuard":"function hasOpenAiKey(c) {\n  return typeof c?.apiKey === \"string\" && c.apiKey.trim().length > 0;\n}","tryCatchPattern":"try {\n  await openaiTts.synthesize(text, model, creds);\n} catch (e) {\n  if (e.message === \"No OpenAI API key configured\") {\n    notifyUser(\"Add an OpenAI API key in provider settings\");\n  } else throw e;\n}","preventionTips":["Run a credential preflight check at gateway startup for enabled TTS providers","Never pass provider credentials objects between providers","Keep keys in the credential store, not ad-hoc env lookups","Add a dashboard health check that flags providers with missing keys"],"tags":["tts","openai","api-key","missing-credentials"],"backgroundTag":"missing-api-key","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}