chenhg5/cc-connect · error
whisper API %d: %s
Error message
whisper API %d: %s
What it means
The Whisper API returned a non-200 status; Transcribe surfaces the status code and the raw response body. This is the server-side error path: auth failures (401), bad model name (404/400), quota/billing (429), or server errors (5xx).
Source
Thrown at core/speech.go:96
if err != nil {
return "", fmt.Errorf("create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+w.APIKey)
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := w.Client.Do(req)
if err != nil {
return "", fmt.Errorf("whisper request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("whisper API %d: %s", resp.StatusCode, string(body))
}
// response_format=text returns plain text; try to handle JSON fallback
text := strings.TrimSpace(string(body))
if strings.HasPrefix(text, "{") {
var jr struct {
Text string `json:"text"`
}
if json.Unmarshal(body, &jr) == nil {
text = jr.Text
}
}
return text, nil
}
// QwenASR implements SpeechToText using the Qwen ASR model via DashScope's
// OpenAI-compatible chat completions API. Unlike Whisper, audio is sent as a
// base64 data URI inside the messages array.View on GitHub (pinned to 4000b2338a)
Solutions
- Read the body in the error message — providers include a JSON reason (e.g. invalid_api_key, model_not_found)
- For 401, verify the API key is correct, active, and has audio API access
- For 404/400 model errors, set Model to one supported by the endpoint (e.g. whisper-large-v3 for Groq)
- For 429, add backoff/retry and check quota/billing
- For 5xx, retry later or check the provider status page
Example fix
// before (Groq endpoint with OpenAI default model) NewOpenAIWhisper(key, "https://api.groq.com/openai/v1", "") // defaults to whisper-1 -> 404 // after NewOpenAIWhisper(key, "https://api.groq.com/openai/v1", "whisper-large-v3")
Defensive patterns
Strategy: try-catch
Validate before calling
if cfg.WhisperAPIKey == "" {
return fmt.Errorf("missing whisper api_key in config")
}
if !slices.Contains(supportedModels, cfg.WhisperModel) {
return fmt.Errorf("model %q not supported by endpoint", cfg.WhisperModel)
} Try / catch
text, err := stt.Transcribe(ctx, audio, format, lang)
if err != nil {
var apiErr *HTTPStatusError // or parse 'whisper API %d:' prefix
if strings.Contains(err.Error(), "whisper API 401") {
slog.Error("whisper auth failed: check api_key")
} else if strings.Contains(err.Error(), "whisper API 429") {
// back off and retry
} else {
slog.Error("whisper API error", "err", err)
}
} Prevention
- Verify the API key works with the audio endpoint before deploying
- Match the model name to the provider (whisper-1 for OpenAI, whisper-large-v3 for Groq)
- Monitor quota/billing to avoid surprise 429s
- Log the response body included in the error — providers explain the exact cause
- Add exponential backoff for 429/5xx responses
When it happens
Trigger: Transcribe called with an invalid or expired API key (401), a Model not available on the endpoint (404/400), exceeded rate limits (429), invalid audio format (400), or provider outage (500/503).
Common situations: Missing/typo'd OPENAI_API_KEY or provider key in config; using whisper-1 against Groq which requires 'whisper-large-v3'; billing/quota exhausted; sending an unsupported audio extension to the endpoint.
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
- yuanbao: sign token API returned %d: %s
- usage endpoint returned status %d: %s
- reasonix: POST %s returned %d: %s
- gitee API returned HTTP %d
- http %d: %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/048a5111a36b0691.
Report an issue: GitHub.