decolua/9router · error · Error
No Gemini API key configured
Error message
No Gemini API key configured
What it means
The Gemini TTS provider's synthesize throws "No Gemini API key configured" when `credentials?.apiKey` is missing. Gemini TTS uses generateContent with AUDIO response modality and authenticates via the `key` query parameter, so without an API key the request cannot even be built correctly.
Source
Thrown at open-sse/handlers/ttsProviders/gemini.js:63
header.writeUInt16LE(CHANNELS, 22);
header.writeUInt32LE(SAMPLE_RATE, 24);
header.writeUInt32LE(byteRate, 28);
header.writeUInt16LE(blockAlign, 32);
header.writeUInt16LE(BITS_PER_SAMPLE, 34);
header.write("data", 36);
header.writeUInt32LE(dataSize, 40);
return Buffer.concat([header, pcmBuffer]);
}
// Build TTS prompt: add "Say [in {language}]:" prefix to force TTS mode
function buildPrompt(text, language) {
if (/:\s/.test(text)) return text; // user already provided style instruction
return language ? `Say in ${language}: ${text}` : `Say: ${text}`;
}
export default {
async synthesize(text, model, credentials, _responseFormat, opts = {}) {
if (!credentials?.apiKey) throw new Error("No Gemini API key configured");
const { modelId, voiceId } = parseGeminiModelVoice(model);
const url = `${TTS_BASE}/${modelId}:generateContent?key=${credentials.apiKey}`;
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contents: [{ parts: [{ text: buildPrompt(text, opts.language) }] }],
generationConfig: {
responseModalities: ["AUDIO"],
speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: voiceId } } },
},
}),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err?.error?.message || `Gemini TTS failed: ${res.status}`);
}
const data = await res.json();View on GitHub (pinned to 90b52e06ff)
Solutions
- Create an API key in Google AI Studio and enter it as the Gemini provider's API key in the 9Router dashboard.
- Ensure the key is stored under `credentials.apiKey` — the exact field this guard checks.
- Verify the key works: `curl "https://generativelanguage.googleapis.com/v1beta/models?key=$KEY"` should list models.
- If you set GEMINI_API_KEY / GOOGLE_API_KEY in env, confirm it is actually passed into the provider credentials object rather than just exported.
Example fix
// before
await gemini.synthesize(text, "gemini-2.5-flash-preview-tts/Kore", {}); // no apiKey
// after
const creds = { apiKey: process.env.GEMINI_API_KEY };
if (!creds.apiKey) throw new Error("Set GEMINI_API_KEY for Gemini TTS");
await gemini.synthesize(text, "gemini-2.5-flash-preview-tts/Kore", creds); Defensive patterns
Strategy: validation
Validate before calling
function requireGeminiCreds(creds) {
if (typeof creds?.apiKey !== "string" || !creds.apiKey.trim()) {
throw new Error("Gemini TTS needs an API key (Google AI Studio) configured as credentials.apiKey");
}
return { apiKey: creds.apiKey.trim() };
} Type guard
function hasGeminiKey(creds) {
return typeof creds === "object" && creds !== null && typeof creds.apiKey === "string" && creds.apiKey.trim() !== "";
} Try / catch
try {
const audio = await gemini.synthesize(text, model, creds);
} catch (e) {
if (e.message === "No Gemini API key configured") {
return res.status(400).json({ error: "Add a Gemini API key in the dashboard before using Gemini TTS" });
}
throw e;
} Prevention
- Create the key in Google AI Studio and store it under the Gemini provider's `apiKey`.
- Note this provider needs an API key, not OAuth credentials.
- Add a startup check that validates the key against the models list endpoint.
- Fail fast at config load when Gemini TTS is enabled without a key.
When it happens
Trigger: Routing a TTS request to the Gemini provider while no Gemini API key is configured: provider enabled in 9Router without credentials, key stored under a field other than `apiKey`, key removed later, or synthesize called directly with null credentials.
Common situations: Fresh setup where the Gemini API key was never entered in the dashboard; using an OAuth-based Gemini credential (which this provider does not read — it needs `apiKey`); key expired/deleted in Google AI Studio; env var set but not wired into the provider credentials object.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- ElevenLabs API key required
- No OpenAI API key configured
- No OpenRouter API key configured
- xiaomi-mimo API key required
- Upstream error (${res.status})
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/76d83f2dd3410054.
Report an issue: GitHub.