chenhg5/cc-connect · error
gemini stt API
Error message
gemini stt API %d: %s
What it means
Thrown by GeminiSTT.Transcribe in core/speech.go when the Gemini API returns a non-200 HTTP status. The error embeds the status code and the raw response body (Gemini error JSON typically explains invalid API key, bad model, quota exhaustion, or malformed request).
Solutions
- Read the status code and body in the error: 401/403 -> fix the API key; 404 -> fix the model name; 400 -> check audio format/MIME; 429 -> wait or raise quota.
- Verify the Gemini API key is set and valid in config.toml/env.
- Confirm the configured model exists for your account/region (Google AI Studio model list).
- Convert audio to a supported format (mp3) via ConvertAudioToMP3.
- For 429/5xx, retry with exponential backoff.
Example fix
// before model = "gemini-pro" // does not accept audio -> 400 // after model = "gemini-1.5-flash" // audio-capable model, valid API key
Defensive patterns
Strategy: try-catch
Validate before calling
if g.APIKey == "" { return errors.New("gemini: missing API key") }
if !strings.Contains(g.Model, "gemini") { return fmt.Errorf("gemini: suspicious model name %q", g.Model) } Try / catch
text, err := stt.Transcribe(ctx, audio)
if err != nil {
if strings.Contains(err.Error(), "gemini stt API 429") {
return "", ErrRateLimited // back off and retry later
}
if strings.Contains(err.Error(), "gemini stt API 40") {
return "", ErrConfigInvalid // key/model/audit request problem
}
return err
} Prevention
- Validate the Gemini API key at startup (cheap models:list call or doctor check).
- Keep model names current — preview models get retired.
- Send only supported audio MIME types (convert to mp3 first).
- Watch quota usage; back off on 429 with exponential delay.
- Read the error body: Gemini includes a human-readable reason in JSON.
When it happens
Trigger: The POST to {BaseURL}/models/{model}:generateContent responds with any status other than 200: 400 invalid request/unsupported audio MIME, 401/403 invalid or missing API key, 404 unknown model name, 429 quota exceeded, 500/503 Gemini outage.
Common situations: Missing or revoked GEMINI/Google AI Studio API key; model name typo (e.g. gemini-1.5-flash vs deleted preview version); audio MIME type not supported by the model; free-tier quota exhausted; regional blocking of the API.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- gemini stt: request
- qwen asr API
- gemini stt: create request
- gemini stt: read response
- api returned status
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/8e7b1886c1fc6f73.
Report an issue: GitHub.
Appendix: source
Thrown at core/speech.go:277
if err != nil {
return "", fmt.Errorf("gemini stt: create request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-goog-api-key", g.APIKey)
resp, err := g.Client.Do(req)
if err != nil {
return "", fmt.Errorf("gemini stt: request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("gemini stt: read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("gemini stt API %d: %s", resp.StatusCode, string(body))
}
var result struct {
Candidates []struct {
Content struct {
Parts []struct {
Text string `json:"text"`
} `json:"parts"`
} `json:"content"`
} `json:"candidates"`
}
if err := json.Unmarshal(body, &result); err != nil {
return "", fmt.Errorf("gemini stt: parse response: %w", err)
}
if len(result.Candidates) == 0 || len(result.Candidates[0].Content.Parts) == 0 {
return "", fmt.Errorf("gemini stt: empty response")
}
View on GitHub (pinned to 4000b2338a)